常用于数据清洗
df.notnull() 返回一个bool型的DataFrame
df.Q1.notna() 返回一个 bool型的Series
df.loc[x,y] # 是—个非常强大的数据选择函数’其中x代表行’y代表列’行和列都支持条件表达式,也支持类似列表那样的切片
df.iloc[x,y] # 类似df.loc[x,y],loc针对列名、索引;iloc针对行、列排列序号
pandas中的索引可以重复,但业务上一般要求索引唯一。
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’)# 效果同上
# 索引
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)
pd.IndexSlice 可以创建一个切片对象,轻松执行复杂的索引切片操作
idx = pd.IndexSlice
idx[0] # 0
idx[:] # slice(None,None,None) 起始位置,结束位置,步长
idx[0,'x'] # (0,'x')
idx[0:3] # slice(0,3,None)
idx[0:5,'x':'y'] #(slice(0,5,None),slice('x','y',None))
DataFrame 的合并都是逐行进行的(默认设置是axis=0)
join 和 join_axes 参数设置合并方式。默认使用join=‘outer’(并集),可以通过join参数指定合并方式。
另一种合并方式是直接确定结果使用的列名,设置 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)
# A B
# 0 A0 B0
# 1 A1 B1
# 2 A2 B2
# 3 A3 B3
通过keys指定层级索引
pd.concat([x,y],keys=['x','y'])
# A B
# x 0 A0 B0
# 1 A1 B1
# y 0 A2 B2
# 1 A3 B3
与 Python 列表中的 append() 和 extend() 方法不同,Pandas 的 append() 不直接更新原有对象的值,而是为合并后的数据创建一个新对象。因此,它不能被称之为一个非常高效的解决方案,因为每次合并都需要重新创建索引和数据缓存。
df1 = make_df('AB',[1,2])
df2 = make_df('AB',[3,4])
df1.append(df2) # 同pd.concat([df1,df2])
函数实现了三种数据连接的类型:一对一、多对一和多对多
df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],
'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
# employee group
# 0 Bob Accounting
# 1 Jake Engineering
# 2 Lisa Engineering
# 3 Sue HR
df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],
'hire_date': [2004, 2008, 2012, 2014]})
# employee hire_date
# 0 Lisa 2004
# 1 Bob 2008
# 2 Jake 2012
# 3 Sue 2014
df3 = pd.merge(df1,df2) # 按照共有列employee连接
# employee group hire_date
# 0 Bob Accounting 2008
# 1 Jake Engineering 2012
# 2 Lisa Engineering 2004
# 3 Sue HR 2014
df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', 'HR'],
'supervisor': ['Carly', 'Guido', 'Steve']})
# group supervisor
# 0 Accounting Carly
# 1 Engineering Guido
# 2 HR Steve
pd.merge(df3,df4) # 按照共有列group连接
# employee group hire_date supervisor
# 0 Bob Accounting 2008 Carly
# 1 Jake Engineering 2012 Guido
# 2 Lisa Engineering 2004 Guido
# 3 Sue HR 2014 Steve
df5 = pd.DataFrame({'group': ['Accounting', 'Accounting', 'Engineering',
'Engineering', 'HR', 'HR'],
'skills': ['math', 'spreadsheets', 'coding', 'linux',
'spreadsheets', 'organization']})
# group skills
# 0 Accounting math
# 1 Accounting spreadsheets
# 2 Engineering coding
# 3 Engineering linux
# 4 HR spreadsheets
# 5 HR organization
pd.merge(df1,df5) # 根据group列合并(多对多会出现笛卡尔积)
# employee group skills
# 0 Bob Accounting math
# 1 Bob Accounting spreadsheets
# 2 Jake Engineering coding
# 3 Jake Engineering linux
# 4 Lisa Engineering coding
# 5 Lisa Engineering linux
# 6 Sue HR spreadsheets
# 7 Sue HR organization
pd.merge() 的默认行为:它会将两个输入的一个或多个共同列作为键进行合并。但由于两个输入要合并的列通常都不是同名的,因此 pd.merge() 提供了一些参数处理这个问题。
这个参数只能在两个 DataFrame 有共同列名的时候才可以使用。
pd.merge(df1, df2, on=‘employee’) # 与pd.merge(df1, df2)效果一样
有时需要合并两个列名不同的数据集
df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
'salary': [70000, 80000, 120000, 90000]})
# name salary
# 0 Bob 70000
# 1 Jake 80000
# 2 Lisa 120000
# 3 Sue 90000
df1中的employee与df3中的name标识一个意思,可用过下面的方法连接
pd.merge(df1, df3, left_on="employee", right_on="name")
# employee group name salary
# 0 Bob Accounting Bob 70000
# 1 Jake Engineering Jake 80000
# 2 Lisa Engineering Lisa 120000
# 3 Sue HR Sue 90000
# 获取的结果中会有一个多余的列,drop()方法将这列去掉
# pd.merge(df1, df3, left_on="employee", right_on="name").drop('name',axis=1)
除了合并列之外,还可以合并索引。
df1a = df1.set_index('employee')
df2a = df2.set_index('employee')
pd.merge(df1a, df2a, left_index=True, right_index=True)
# group hire_date
# employee
# Bob Accounting 2008
# Jake Engineering 2012
# Lisa Engineering 2004
# Sue HR 2014
将索引与列混合使用,那么可以通过结合 left_index 与right_on,或者结合 left_on 与 right_index 来实现。
pd.merge(df1a, df3, left_index=True, right_on='name')
# group name salary
# 0 Accounting Bob 70000
# 1 Engineering Jake 80000
# 2 Engineering Lisa 120000
# 3 HR Sue 90000
可以按照索引进行数据合并
df1a.join(df2a) 效果同pd.merge(df1a, df2a, left_index=True, right_index=True)
当一个值出现在一列,却没有出现在另一列时,就需要考虑集合操作规则了;how 参数设置连接方式,参数支持的数据连接方式有 ‘inner’、 ‘outer’、‘left’ 和 ‘right’。
df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'],
'food': ['fish', 'beans', 'bread']},
columns=['name', 'food'])
# name food
# 0 Peter fish
# 1 Paul beans
# 2 Mary bread
df7 = pd.DataFrame({'name': ['Mary', 'Joseph'],
'drink': ['wine', 'beer']},
columns=['name', 'drink'])
# name drink
# 0 Mary wine
# 1 Joseph beer
pd.merge(df6, df7, how='inner') # 与pd.merge(df6, df7)效果相同
# name food drink
# 0 Mary bread wine
pd.merge(df6, df7, how='outer') # df6 与 df7的并集
# name food drink
# 0 Peter fish NaN
# 1 Paul beans NaN
# 2 Mary bread wine
# 3 Joseph NaN beer
pd.merge(df6, df7, how='left') # 左连接(以df6数据为准)
# name food drink
# 0 Peter fish NaN
# 1 Paul beans NaN
# 2 Mary bread wine
输出结果中有两个重复的列名,pd.merge() 函数会自动为它们增加后缀 _x 或 _y
df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
'rank': [1, 2, 3, 4]})
df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'],
'rank': [3, 1, 4, 2]})
pd.merge(df8, df9, on="name")
# name rank_x rank_y
# 0 Bob 1 3
# 1 Jake 2 1
# 2 Lisa 3 4
# 3 Sue 4 2
可以通过 suffixes 参数自定义后缀名
pd.merge(df8, df9, on="name", suffixes=["_L", "_R"])
# name rank_L rank_R
# 0 Bob 1 3
# 1 Jake 2 1
# 2 Lisa 3 4
# 3 Sue 4 2