本章主要内容为对存在于不同文件的数据或者以不易于进行分析的格式存储的数据进行数据联合、连接以及重新排列。
1. 分层索引
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]])
data
a 1 -0.620699
2 0.246469
3 -2.736904
b 1 0.736691
3 0.448997
c 1 0.567007
2 0.698084
d 2 0.133280
3 -0.173206
dtype: float64
data.index # 复合索引
MultiIndex([('a', 1),
('a', 2),
('a', 3),
('b', 1),
('b', 3),
('c', 1),
('c', 2),
('d', 2),
('d', 3)],
)
a. 通过分层索引对象(也称部分索引),可以选择数据的子集:
data['b']
1 0.736691
3 0.448997
dtype: float64
data[['b', 'd']] # data.loc[['b', 'd']] 效果一致
b 1 0.736691
3 0.448997
d 2 0.133280
3 -0.173206
dtype: float64
data["b": "c"] # 前闭后闭
b 1 0.736691
3 0.448997
c 1 0.567007
2 0.698084
dtype: float64
b. 内部层级的索引也可以:
data.loc[:, 2] # loc是标签索引,2表示内层的索引,非整数iloc索引
a 0.246469
c 0.698084
d 0.133280
dtype: float64
c. 分层索引在重塑数据和数组透视表中应用广泛,常用stack和unstack方法:
data.unstack() # Series的分层索引转化为DataFrame
1 2 3
a -0.620699 0.246469 -2.736904
b 0.736691 NaN 0.448997
c 0.567007 0.698084 NaN
d NaN 0.133280 -0.173206
data.unstack().stack() # stack 与 unstack是逆操作
a 1 -0.620699
2 0.246469
3 -2.736904
b 1 0.736691
3 0.448997
c 1 0.567007
2 0.698084
d 2 0.133280
3 -0.173206
dtype: float64
d. 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.index.names = ['key1', 'key2']
frame.columns.names = ['state', 'color']
frame
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
2 3 4 5
b 1 6 7 8
2 9 10 11
e. 创建多层索引的方法有三种:元组列表 / 特定结构 / 笛卡尔积,具体内容参见收藏博客内容。
1.1 重排序和层级排序
a. swaplevel 可以将内外层的索引进行变更对调:
frame.swaplevel('key1', 'key2')
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
b. sort_index 只能在单一层级上对数据进行排序,可以在层级变换时配合使用来按照想要的索引排序:
frame.sort_index(level=1)
state Ohio Colorado
color Green Red Green
key1 key2
a 1 0 1 2
b 1 6 7 8
a 2 3 4 5
b 2 9 10 11
frame.swaplevel(0, 1).sort_index(level=0) # 排序的level 0 是层级变换后的外层索引
state Ohio Colorado
color Green Red Green
key2 key1
1 a 0 1 2
b 6 7 8
2 a 3 4 5
b 9 10 11
1.2 按层级进行汇总统计
DataFrame 和 Series中很多描述性统计和汇总性统计都有level选项,可以指定想要进行聚合的轴。
frame.sum(level='key2')
state Ohio Colorado
color Green Red Green
key2
1 6 8 10
2 12 14 16
frame.sum(level='color', axis=1)
color Green Red
key1 key2
a 1 2 1
2 8 4
b 1 14 7
2 20 10
1.3 使用DataFrame 的列进行索引
a. 有些情况下,我们想要将DataFrame中的某些列转换为行索引,可以通过set_index来实现:
frame = pd.DataFrame({
'a': range(7), 'b': range(7, 0, -1),
'c': ['one', 'one', 'one', 'two', 'two',
'two', 'two'],
'd': [0, 1, 2, 0, 1, 2, 3]})
frame
a b c d
0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
3 3 4 two 0
4 4 3 two 1
5 5 2 two 2
6 6 1 two 3
将 c 列和 d 列作为分层索引:
frame2 = frame.set_index(["c", "d"])
frame2
a b
c d
one 0 0 7
1 1 6
2 2 5
two 0 3 4
1 4 3
2 5 2
3 6 1
默认情况下,被作为索引的列会从数据列中移除,也可以通过drop参数来保留:
frame.set_index(["c", "d"], drop=False)
a b c d
c d
one 0 0 7 one 0
1 1 6 one 1
2 2 5 one 2
two 0 3 4 two 0
1 4 3 two 1
2 5 2 two 2
3 6 1 two 3
b. reset_index是set_index的反操作,可以将作为分层索引的列重新移回列中:
frame2.reset_index()
c d a b
0 one 0 0 7
1 one 1 1 6
2 one 2 2 5
3 two 0 3 4
4 two 1 4 3
5 two 2 5 2
6 two 3 6 1
2. 联合与合并数据集
2.1 数据库风格的DataFrame连接
a. 通过一个或多个键连接行的方式来联合数据集是关系型数据库常用的合并或连接操作。pandas中的merge(合并)函数可以实现各种join操作:
df1 = pd.DataFrame({
'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1': range(7)})
df2 = pd.DataFrame({
'key': ['a', 'b', 'd'],
'data2': range(3)})
df1
key data1
0 b 0
1 b 1
2 a 2
3 c 3
4 a 4
5 a 5
6 b 6
df2
key data2
0 a 0
1 b 1
2 d 2
pd.merge(df1, df2) # 未指定连接的键,merge自动将重叠列名作为连接键
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
pd.merge(df1, df2, on='key') # 结果同上
pd.merge(df1, df2, how='outer') # 外连接
key data1 data2
0 b 0.0 1.0
1 b 1.0 1.0
2 b 6.0 1.0
3 a 2.0 0.0
4 a 4.0 0.0
5 a 5.0 0.0
6 c 3.0 NaN
7 d NaN 2.0
如果每个对象的列