取值操作
常用方式
- df[‘Q1’] # 选择‘Q1’列,同df.Q1,返回一个Series
- df[[‘name’,‘Q1’]] # 选择多列,注意括号
- df[0:3] # 取前三行
- df[0:10:2] # 0到前10行中每两行取一次数据(python 切片操作: start : end : steps)
- df.head() # 查看前5条记录
- df.tail() # 查看后5条记录
- df.sample() # 随机抽查5条记录
掩码取值
常用于数据清洗
- df[df.Q1.notna()] # 取出有效的行 (Q1不为NaN的行)
- df.[df.notnull().all(1)] # 获取所使用包含NaN的行;df.notnull().all(1):返回行是否不包含NaN;df.notnull().all(0):返回列是否不包含NaN
df.notnull() 返回一个bool型的DataFrame
df.Q1.notna() 返回一个 bool型的Series
loc函数
df.loc[x,y] # 是—个非常强大的数据选择函数’其中x代表行’y代表列’行和列都支持条件表达式,也支持类似列表那样的切片
- df.loc[:,[‘name’,‘Q1’]] # 选择所有行,‘name’、'Q1’列;效果同df[[‘name’,‘Q1’]]
- df.loc[‘Ben’,‘Q1’:‘Q4’] # 选择行列(Ben Q1到Q4的成绩)
- df.loc[‘Eorge’:‘Alexander’,‘team’:‘Q4’] # 选择行列,指定行区间
iloc函数
df.iloc[x,y] # 类似df.loc[x,y],loc针对列名、索引;iloc针对行、列排列序号
列名操作
增加列
- df[‘one’] = 1 # 增加一个固定值的列
- df[‘total’] = df.Q1+df.Q2+df.Q3+df.Q4 # 增加成绩总和
- df[‘total’] = df.loc[:,‘Q1’:‘Q4’].apply(lambda x: sum(x),axis=1) # 效果同上
- df[‘total’] = df.sum(axis=1) # 把所有为数字的列相加
- df[‘avg’] = df.total/4 # 增加平均成绩列
修改列(行)名
reindex
- df.reindex(columns=colmnsList) # 修改列名;colmnsList为列名列表;如果使用命名参数,修改的时索引名称
- df.reindex(colmnsList) # 修改的时索引名称
rename
- data.rename(index={‘OHIO’: ‘INDIANA’}, columns={‘three’: ‘pekaboo’}) # 根据字典替换对应的列/索引名称
- data.rename(index={‘OHIO’: ‘INDIANA’}, inplace=True) # 在源数据上修改
删除列(行)
- df.drop([‘index1’,’index2’]) # 删除多行
- df.drop(index1) # 删除单行
- df.drop([‘colmn1’,’ colmn 2’],axis=1) # 删除多列
- df.drop(colmn1,axis=’columns’) # 删除列
索引操作
pandas中的索引可以重复,但业务上一般要求索引唯一。
创建索引
- df.set_index(‘name’) # 设置name列为索引
- df.set_index([‘name’,‘team’]) #设置层级索引
- df.set_index([df.name.str[0],‘name’]) #设置层级索引
- df.set_index(‘name’,inplace=True) #设置 inplace=True参数可以直接修改原df
- df.set_index(‘name’,drop=False) # 保留原列
- df.set_index(‘name’,append=True) # 保留原索引
重置索引
-
df.reset_index() # 清除索引
-
df.reset_index(inplace=True) #设置 inplace=True参数可以直接修改原df
-
df.reset_index([‘month’,‘year’]).reset_index(level=1) # year二级索引清除;level=0表示一级索引
-
df.reset_index([‘month’,‘year’]).reset_index(level=‘year’)# 效果同上
索引其他常用方法
- df.index.astype(‘int64’) # 转换类型
- df.index.rename(‘number’) # 修改索引的名称
- df.index.sort_values(ascending=False) # 排序,倒序
- df.index.rename(‘grade’,inpalce=True) # 重命名索引
- df.index.rename([‘species’,‘year’]) # 多层,重命名索引
- df.index.T # 转置,在多层索引里很有用
- df.index.set_names(‘species’,level=0) # 设置名称
- df.index.set_names([‘kind’,‘year’],inplace = True) # 设置名称
多级 行、列索引
index_arrays=[[1,1,2,2],['男','女','男','女']]
columns_arrays = [['2019','2019','2020','2020'],
['上半年','下半年','上半年','下半年']]
index = pd.MultiIndex.from_arrays(index_arrays,names=('班级','性别'))
columns = pd.MultiIndex.from_arrays(colums_arrays,names=('年份','学期'))
df = pd.DataFrame([(88,99,88,99),(77,88,97,98),(67,89,54,78),(34,67,89,54)],
columns=columns,index=index)
- df[0:3] # 取一级索引的前3行(实际数可能多于三行,因为取得是一级索引,一级索引下可能有多条二级索引数据)
- df.loc[(1,“男”)] # 同时使用一、二级索引获取数据(将需要查询的索引条件组成一个元组)
- df.loc[(1,“男”),(slice(None),‘下半年’)] # 行、列同时查询,slice(None)可以在元组中占位
- df.loc[‘2020’,slice(None))] # 只看2020年的数据
- df.loc[(slice(None),‘女’),:] # 只看女生
层级索引切片
pd.IndexSlice 可以创建一个切片对象,轻松执行复杂的索引切片操作
idx = pd.IndexSlice
idx[0]
idx[:]
idx[0,'x']
idx[0:3]
idx[0:5,'x':'y']
- df.loc[idx[:,[‘男’]],:] # 只显示男生
- df.loc[:,idx[:,[’ 上半年’]]] # 只显示上半年
数据合并
concat
DataFrame 的合并都是逐行进行的(默认设置是axis=0)
- df3 =make_df(‘AB’,[0,1])
- df4=make_df(‘CD’,[0,1])
- pd.concat([df3,df4],axis=1) # 列拼接 (横向)合并后会有2行4列
- pd.concat([df3,df4]) # 行拼接 (纵向) 合并后会有4行4列,缺失的数据会用NaN填充
join、join_axes 参数
join 和 join_axes 参数设置合并方式。默认使用join=‘outer’(并集),可以通过join参数指定合并方式。
- df5 =make_df(‘ABC’,[0,1])
- df6=make_df(‘BCD’,[0,1])
- pd.concat([df5, df6], join=‘inner’) # 合并列名交集(合并后只有B、C两列)
另一种合并方式是直接确定结果使用的列名,设置 join_axes 参数,指定列名
pd.concat([df5, df6], join_axes=[df5.columns]) # 指定使用df5的列名,df6中不存在的列名合并时自动删除
索引问题
pd.concat 会保留索引,即使索引重复
想要检测 pd.concat() 合并的结果中是否出现了重复的索引,可以设置 verify_integrity 参数。将参数设置为 True,合并时若有索引重复就会触发异常。
try:
pd.concat([x,y],verify_integrity=True)
except Exception as e:
print(e)
Indexes have overlapping values: Int64Index([0, 1], dtype='int64')
可以通过设置 ignore_index 为True忽略重复索引,合并时会生成新的索引
pd.concat([x,y],ignore_index=True)
通过keys指定层级索引
pd.concat([x,y],keys=['x','y'])
append
与 Python 列表中的 append() 和 extend() 方法不同,Pandas 的 append() 不直接更新原有对象的值,而是为合并后的数据创建一个新对象。因此,它不能被称之为一个非常高效的解决方案,因为每次合并都需要重新创建索引和数据缓存。
df1 = make_df('AB',[1,2])
df2 = make_df('AB',[3,4])
df1.append(df2)