Python医学数据分析

# 第五章 Pandas入门
import pandas as pd    # 导入Pandas库

# Pandas数据结构
# 通过列表创建Series
obj = pd.Series([2, 4, 3, 6])
#obj = pd.Series(["2","4","3","6"]) 
obj
i = ['a', 'b', 'c', 'd']
v = [2, 4, 3, 6]
obj = pd.Series(data = v, index = i)
obj
obj.index #查看索引(数据标签)
obj.values #查看数据值序列
# 通过字典创建Series
data = {'a': 32, 'b': 24, 'c': 45, 'd': 36}
obj = pd.Series(data, name = "age")
obj
obj.index
obj.values
obj.name


# 创建DataFrame
# 通过等长列表创建表格型数据
data = {'id': ['a', 'b', 'c', 'd'],
        'age': [32, 24, 45, 36],
        'sex': ['M', 'F', 'M', 'F'],
        'height': [175, 161, 176, 158]}
df = pd.DataFrame(data)
df
# 可用“columns”添加列索引
df1 = pd.DataFrame(data, columns = ['id', 'sex', 'age', 'height'])
df1
# 可用参数“columns”指定列索引和顺序
df11 = pd.DataFrame(data, columns = ['sex', 'id', 'age', 'height'])
df11
# 如果传入的列索引在数据中找不到,则会产生NaN值
df2 = pd.DataFrame(data, columns = ['id', 'sex', 'age', 'weight'])
df2
# 可用参数“index”添加行索引
df3 = pd.DataFrame(data, 
                   columns = ['age', 'sex', 'height'], 
                   index = ['a', 'b', 'c', 'd'])
df3
# 添加行名、列名,为index和columns属性设置name
df3.index.name = 'id'
df3.columns.name = 'variables'
df3
df3.values # 
df3.dtypes # 各列的数据类型
df3.ndim # 维度数,一维、二维、三维
df3.shape # 形状,即几行几列


# Pandas数据操作
# 创建一个Series
data = {'b': 24, 'a': 32, 'd': 36, 'c': 45}
s = pd.Series(data, name = "age")
s
# reindex函数重建series的索引
s1 = s.reindex(['a', 'b', 'c', 'd', 'e'])
s1
# 通过函数isnull或notnull进行判断
s1.isnull()
s1.notnull()

# 创建一个DataFrame
data = {'id': ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
        'age': [32, 24, 45, 36, 25, 32, 47, 39],
        'sex': ['M', 'F', 'M', 'F', 'F', 'M', 'F', 'M'],
        'height': [175, 161, 176, 158, 166, 174, 168, 170], 
        'weight': [62.9, 53.4, 73.5, 55.9, 56.2, 71.0, 68.5, 75.4]}
df = pd.DataFrame(data)
df
# 通过函数set_index可将DataFrame里的某一列设为行索引
df = df.set_index('id')
df
# 同样可以通过reindex函数重建行索引
df.reindex(['b', 'c', 'h', 'g', 'a', 'e', 'd', 'g'])
# 要重建列索引,只需设置reindex的参数“axis”为1或columns
df.reindex(['sex', 'age', 'weight', 'height'], axis = 'columns')

# 查询与编辑
# 通过列索引标签获取DataFrame的一列或多列数据
w1 = df['age']
w1
df.age

w2 = df[['age', 'sex']]
w2
# 但在选取列时不能使用切片的方式

# 通过行索引位置的切片形式可以获取DataFrame的一行或多行数据
df[1:2]         # 选取前2行,注意:整数索引切片是前闭后开,标签索引切片是前闭后闭,这点尤其要注意
df["a":"b"]
df[1:3]        # 选取第2、3行
df.head()      # 默认选取前5行
df.tail()      # 默认选取后5行
df.sample(3)   # 随机抽取3行
df.sample(frac = 0.8)  # 随机抽取80%的行
df[df['sex'] == 'M']       # 选取性别('sex')为男性('M')的行

# 针对DataFrame的子集选择,Pandas提供了特殊的索引符号iloc和loc
# 其中iloc根据行索引和列索引的位置选取子集
# loc根据行索引和列索引的名称选取子集
df.iloc[1:5, [0, 2]]      # 选取第2行到5行,第1列和第3列
df.loc[['b', 'd', 'e'], ['age', 'sex']]  # 选取第b、d、e行,age和sex列
df.loc[:'c', ['height', 'weight']]
df.iloc[:, :3] [df.age > 30]

# 增加数据,可以用append函数将字典传入
data1 = {'age': 42, 'sex': 'M', 'height': 178, 'weight': 78.2}
df.append(data1, ignore_index = True) #由于pandas库的更新,2.0及以后得版本把append()这个方法给删除了
df
#pip install pandas==1.5.3
df111 = pd.concat([df, pd.DataFrame([data1])], ignore_index = True)
df111
df['bmi'] = df['weight']/(df['height']/100) ** 2
df

# 删除数据
df.drop('a')     # 删除index为“a”的行
df.drop('bmi', axis = 1)   # 删除变量bmi,“axis”指定删除行(0)还是列(1)
df.duplicated('age') # 识别重复值
any(df.duplicated('age')) # 只有有重复值,返回true
df.drop_duplicates('age') # 删除除第一个外重复值行

# 按照某个变量的值的大小顺序进行排序
df.sort_values(by = 'age')
df.sort_values(by = 'age', ascending = False)
df.sort_values(by = ['age', 'height']) #在age相等时,再以height的值从小到大排序

# 数据的导入和导出
df
df.to_csv('subjects.csv')  # 导出为csv文件
df.to_excel('subjects.xlsx')  # 导出为Excel文件
#pip install openpyxl
#import openpyxl

pd.read_csv('subjects.csv', index_col = 0) # index_col = 0 表示将数据中的第一列设为行索引
pd.read_excel('subjects.xlsx', index_col = 0)
#mydata = pd.read_spss('subjects.sav')
#type(mydata)


# 数据预处理
# 合并数据集
data1 = {'id': range(1, 6),
        'sex': ['M', 'F', 'M', 'F', 'F'],
        'age': [32, 24, 45, 36, 25]}
df1 = pd.DataFrame(data1)
df1
data2 = {'id': range(6, 11),
        'sex': ['M', 'F', 'M', 'M', 'F'],
        'age': [52, 36, 28, 34, 26]}
df2 = pd.DataFrame(data2)
df2

# 纵向合并,可用pd.concat函数合并,但合并的两个数据集必须拥有相同的变量
pd.concat([df1, df2], ignore_index = True)   # 合并df1和df2
# 其中ignore_index = True是忽略原始索引,让函数自动生成新的索引

# 横向合并,也用pd.concat函数合并,但要将参数“axis”设为1
data3 = {'days': [28, 57, 15, 7, 19],
        'outcome': ['discharge', 'dead', 'discharge', 'transfer', 'discharge']}
df3 = pd.DataFrame(data3)
df3
pd.concat([df1, df3], axis = 1)

# 按照某个共有变量合并,可用函数pd.merge
data4 = {'id': [2, 1, 3, 5, 4],
        'outcome': ['discharge', 'dead', 'discharge', 'transfer', 'discharge']}
df4 = pd.DataFrame(data4)
df4,df1
pd.merge(df1, df4)

# 缺失值的识别
import numpy as np
iris = pd.read_csv('iris.csv')
iris_na = iris.copy()    
iris_na.loc[:2, 'Sepal_Length'] = np.nan
iris_na.loc[:4, 'Petal_Length'] = np.nan
iris_na
iris_na.isnull().sum() #获取每一列(变量)的缺失值
iris_na.info() #获取各个变量非缺失值的总数、总行数和变量类型等信息

# 缺失值的处理
iris_na.dropna() # 通过dropna函数实现删除缺失值,此为删除有缺失值的行
iris_na.dropna(axis = 1) # 删除有缺失值的列
# 补充缺失值,对于变量呈偏态分布,可以使用中位数填补
iris_na.Sepal_Length.median()
iris_na.Petal_Length.median()
# 用fillna函数进行补充
iris_na.fillna({'Sepal_Length': 5.8, 'Petal_Length': 4.4})
iris_na.fillna(method = 'bfill').iloc[:10, ]

# 数据转换
birthwt = pd.read_csv('birthwt.csv')
birthwt
birthwt.info()
# 替换数据值:可用replace函数替换
s = birthwt.low
s.replace(0, 999)    # 把s中的'0'替换为999
s.replace([0, 1], ['No', 'Yes'])   # 把s中的'0'替换为'No', '1'替换为'Yes'
s.replace({0: 'No', 1: 'Yes'})
birthwt.replace({'low': {0: 'No', 1: 'Yes'},
                 'race': {1: 'White', 2: 'Black', 3: 'Others'}})

# 将数值型变量转为分类变量:可用pd.cut函数实现分组
min(birthwt.age)
max(birthwt.age)
pd.cut(birthwt.age, bins = [13, 25, 35, 45])
pd.cut(birthwt.age, bins = [13, 25, 35, 45],    
       labels = ['14-25', '26-35', '36-45'])
pd.cut(birthwt.age, 4, precision = 2)  # 用等长的四个区间分隔数据
pd.qcut(birthwt.age, 4)  # 用四分位数分隔数据
pd.qcut(birthwt.age, [0, 0.1, 0.5, 0.9, 1])    # 用自定义的分位数分隔数据

#用astype函数转化为分类变量
birthwt.race = birthwt.race.astype('category')
birthwt.info()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值