本章重点
数据可能分散在许多文件或数据库中,存储的形式也不利于分析。本章关注可以聚合、合并、重塑数据的方法。
对于数据分散的情况常使用层次化索引,层次化索引是pandas的⼀项重要功能,它使你能在⼀个轴上拥有多个(两个以上)索引级别。抽象点说,它使你能以低维度形式处理高维度数据。
data=pd.Series(np.random.randn(9),
index=[['a','a','a','b','b','c','c','d','d'],
[1,2,3,1,3,1,2,2,3]])
#输出 注意有两个索引 MultiIndex
#索引之间的“间隔”表示“直接使⽤上⾯的标签
a 1 -1.925518
2 1.053123
3 -0.760436
b 1 0.534796
3 -1.025699
c 1 0.213862
2 -0.483737
d 2 -0.356384
3 -1.010102
dtype: float64
对于⼀个层次化索引的对象,可以使用所谓的部分索引,使用它选取数据子集的操作更简单。
data['a'] #输出 1 -0.446613 2 0.120970 3 0.990672 dtype: float64
切片: 注意先行后列
data.loc[:, 2] # 先行后列 #输出 a 0.895573 c 0.638414 d -1.139403 dtype: float64
层次化索引在数据重塑和基于分组的操作(如透视表生成)中扮演着重要的角色。如通过unstack方法将这段数据重新
安排到⼀个DataFrame中:
data.unstack()
#输出
1 2 3
a 1.987082 -0.351358 -0.685920
b 0.595239 NaN -0.668121
c -0.944251 0.838090 NaN
d NaN 1.353632 -0.998955
unstack的逆运算是stack。
对于⼀个DataFrame,每条轴都可以有分层索引:
frame=pd.DataFrame(np.arange(12).reshape((4,3)),
index=[['a','a','b','b'],[1,2,1,2]],
columns=[['Ohio','Ohio','Colorado'],['Green','Red','Green']])
frame
#输出
Ohio Colorado
Green Red Green
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
有了部分列索引,因此可以轻松选取列分组:
frame['Ohio'] # Green Red a 1 0 1 2 3 4 b 1 6 7 2 9 102.重排与分级排序
有时,你需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。**swaplevel接受两个级别编号或名称,**并返回⼀个互换了级别的新对象(但数据不会发生变化):
frame=pd.DataFrame(np.arange(12).reshape((4,3)),
index=[['a','a','b','b'],[1,2,1,2]],
columns=[['Ohio','Ohio','Colorado'],['Green','Red','Green']])
frame.index.names=['key1','key2']
frame.columns.names=['state','color']
frame.swaplevel('key1','key2') #swaplevel将index对调
#输出 index对调
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
2 a 3 4 5
1 b 6 7 8
2 b 9 10 11
而sort_index则根据单个级别中的值对数据进行排序。交换级别时,常常也会用到sort_index,最终结果就是按照指定顺序进行字母排序了。
3.根据级别汇总统计许多对DataFrame和Series的描述和汇总统计都有⼀个level选项,它用于指定在某条轴上求和的级别。
frame.sum(level='key1') #输出,key1上相同的index求和 ''' state Ohio Colorado color Green Red Green key1 a 3 5 7 b 15 17 19 '''
这其实是利用了pandas的groupby功能,后续将对其进行详细讲解。
4.使用DataFrame的列进行索引人们经常想要将DataFrame的⼀个或多个列当做行索引来用,或者可能希望将行索引变成DataFrame的列。
DataFrame的set_index函数会将其一个或多个列转换为行索引,并创建⼀个新的DataFrame:
frame=pd.DataFrame({'a':range(5),
'b':range(5,0,-1),
'c':['one','one','two','two','two'],
'd':[0,1,2,4,3]})
frame2=frame.set_index(['c','d']) #c,d变成了index.names
frame2
#输出 c d变成行索引,index,c,d变成了index.names
a b
c d
one 0 0 5
1 1 4
two 2 2 3
4 3 2
3 4 1
reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里⾯。
- List item
pandas对象中的数据可以通过⼀些方式进行合并:
- pandas.merge可根据⼀个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的join操作。
- pandas.concat可以沿着⼀条轴将多个对象堆叠到⼀起。
- 实例方法combine_first可以将重复数据编接在⼀起,用⼀个对象中的值填充另⼀个对象中的缺失值。
数据集的合并(merge)或连接(join)运算是通过⼀个或多个键将行链接起来的。这些运算是关系型数据库(基于SQL)的核心。pandas的merge函数是对数据应用这些算法的主要切入点。
df1=pd.DataFrame({'key':['b','b','a','c','a','a','b'],
'data1':range(7)})
df2=pd.DataFrame({'key':['a','b','d'],
'data2':range(3)})
pd.merge(df1,df2) #pd.merge(df1,df2,on='key') 等价
#输出 df1 df2中key都有a,b,按此合并
key data1 data2
0 b 0 1
1 b 1 1
2 b 6 1
3 a 2 0
4 a 4 0
5 a 5 0
上述程序并没有指明要用哪个列进行连接。如果没有指定,merge就会将重叠列的列名当做键。不过,最好明确指定⼀下。
如果列名不同,也可分别指定 pd.merge(df3,df4,left_on=‘lkey’, right_on=‘rkey’)
结果里面c和d以及与之相关的数据消失了。默认情况下,merge做的是“内连接”;结果中的键是交集。其他方式还有"left"、“right"以及"outer”。外连接求取的是键的并集,组合了左连接和右连接的效果。
| 选项 | 说明 |
|---|---|
| inner | 使用两个表都有键 |
| left | 使用左表所有键 |
| lright | 使用右表所有键 |
| outer | 使用两个表所有键 |
多对多的合并有些不直观。看下面的例子
2.索引上的合并


