pandas 层次化索引的实现方法
本文详细介绍 pandas 中层次化索引(MultiIndex)的创建、数据选取、排序及重塑方法。涵盖 Series 和 DataFrame 的多级索引构建,演示 swaplevel、sortlevel 及 set_index/reset_index 等核心函数的具体用法,帮助开发者高效处理复杂数据结构。
层次化索引概述
层次化索引是 pandas 库中的一项核心功能,它允许在单一轴上设置两个或更多的索引层级,从而支持更复杂的数据结构操作。
创建层次化索引 Series
要创建带有层次化索引的 Series,可以使用由列表或数组组成的列表作为索引参数。
data=Series(np.random.randn(10),
index=[['a','a','a','b','b','b','c','c','d','d'],
[1,2,3,1,2,3,1,2,2,3]])
data
Out[6]:
a 1 -2.842857
2 0.376199
3 -0.512978
b 1 0.225243
2 -1.242407
3 -0.663188
c 1 -0.149269
2 -1.079174
d 2 -0.952380
3 -1.113689
dtype: float64
这种带有多级索引的 Series 在格式化输出时,索引层级之间会显示“间隔”,这表示该位置直接沿用了上一层级的标签。
data.index
Out[7]:
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
labels=[[0, 0, 0, 1, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 1, 2, 0, 1, 1, 2]])
层次化索引的数据选取
对于拥有层次化索引的对象,选取子集数据的操作非常直观。
data['b']
Out[8]:
1 0.225243
2 -1.242407
3 -0.663188
dtype: float64
data['b':'c']
Out[10]:
b 1 0.225243
2 -1.242407
3 -0.663188
c 1 -0.149269
2 -1.079174
dtype: float64
data.ix[['b','d']]
__main__:1: DeprecationWarning:
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing
See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
Out[11]:
b 1 0.225243
2 -1.242407
3 -0.663188
d 2 -0.952380
3 -1.113689
dtype: float64
甚至可以在“内层”索引中进行数据选取。
data[:,2]
Out[12]:
a 0.376199
b -1.242407
c -1.079174
d -0.952380
dtype: float64
数据重塑与 DataFrame 应用
层次化索引在数据重塑以及基于分组的聚合操作中发挥着关键作用。
可以通过 unstack 方法将层次化索引的数据重新排列并转换到 DataFrame 中。
data.unstack()
Out[13]:
1 2 3
a -2.842857 0.376199 -0.512978
b 0.225243 -1.242407 -0.663188
c -0.149269 -1.079174 NaN
d NaN -0.952380 -1.113689
#unstack的逆运算是stack
data.unstack().stack()
Out[14]:
a 1 -2.842857
2 0.376199
3 -0.512978
b 1 0.225243
2 -1.242407
3 -0.663188
c 1 -0.149269
2 -1.079174
d 2 -0.952380
3 -1.113689
dtype: float64
对于 DataFrame 而言,其每一条轴(行或列)都可以拥有分层索引。
frame=DataFrame(np.arange(12).reshape((4,3)),
index=[['a','a','b','b'],[1,2,1,2]],
columns=[['Ohio','Ohio','Colorado'],
['Green','Red','Green']])
frame
Out[16]:
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
Out[22]:
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
得益于分部的列索引,用户可以轻松选取特定的列分组。
frame['Ohio']
Out[23]:
color Green Red
key1 key2
a 1 0 1
2 3 4
b 1 6 7
2 9 10
重排分级排序
重排分级排序
有时需要调整某条轴上各级别的顺序,或者根据指定级别上的值对数据进行排序。swaplevel 函数接受两个级别编号或名称,返回一个交换了级别的新对象(数据内容保持不变)。
frame.swaplevel('key1','key2')
Out[24]:
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
sortlevel 函数则根据单个级别中的值对数据进行排序。在交换级别后,通常配合使用 sortlevel,以确保最终结果是有序的。
frame.swaplevel(0,1)
Out[27]:
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
#交换级别0,1(也就是key1,key2)
#然后对axis=0进行排序
frame.swaplevel(0,1).sortlevel(0)
__main__:1: FutureWarning: sortlevel is deprecated, use sort_index(level= ...)
Out[28]:
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
根据级别汇总统计
根据级别汇总统计
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel 接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
frame.sum(level='key2')
Out[29]:
state Ohio Colorado
color Green Red Green
key2
1 6 8 10
2 12 14 16
frame.sum(level='color',axis=1)
Out[30]:
color Green Red
key1 key2
a 1 2 1
2 8 4
b 1 14 7
2 20 10
利用 DataFrame 列进行索引转换
使用 DataFrame 的列
可以将 DataFrame 的一个或多个列转换为行索引,或者将现有的行索引转换回 DataFrame 的列。
frame=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
Out[32]:
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
DataFrame 的 set_index 函数会将一个或多个列转换为行索引,并生成一个新的 DataFrame。
frame2=frame.set_index(['c','d'])
frame2
Out[34]:
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
默认情况下,用于建立索引的列会从原 DataFrame 中移除,但可以通过参数将其保留下来。
frame.set_index(['c','d'],drop=False)
Out[35]:
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
reset_index 的功能与 set_index 相反,它会将层次化索引的各级别转移回列中。
frame2.reset_index()
Out[36]:
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













