pandas 层次化索引的实现方法
层次化索引是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。
创建一个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]: a1-2.842857 20.376199 3-0.512978 b10.225243 2-1.242407 3-0.663188 c1-0.149269 2-1.079174 d2-0.952380 3-1.113689 dtype:float64
这就是带MultiIndex索引的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]: 10.225243 2-1.242407 3-0.663188 dtype:float64 data['b':'c'] Out[10]: b10.225243 2-1.242407 3-0.663188 c1-0.149269 2-1.079174 dtype:float64 data.ix[['b','d']] __main__:1:DeprecationWarning: .ixisdeprecated.Pleaseuse .locforlabelbasedindexingor .ilocforpositionalindexing Seethedocumentationhere: http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated Out[11]: b10.225243 2-1.242407 3-0.663188 d2-0.952380 3-1.113689 dtype:float64
甚至可以在“内层”中进行选取:
data[:,2] Out[12]: a0.376199 b-1.242407 c-1.079174 d-0.952380 dtype:float64
层次化索引在数据重塑和基于分组的操作中扮演重要角色。
可以通过unstack方法被重新安排到一个DataFrame中:
data.unstack() Out[13]: 123 a-2.8428570.376199-0.512978 b0.225243-1.242407-0.663188 c-0.149269-1.079174NaN dNaN-0.952380-1.113689 #unstack的逆运算是stack data.unstack().stack() Out[14]: a1-2.842857 20.376199 3-0.512978 b10.225243 2-1.242407 3-0.663188 c1-0.149269 2-1.079174 d2-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]: OhioColorado GreenRedGreen a1012 2345 b1678 291011
各层都可以有名字。如果指定了名称,它们会显示在控制台中(不要将索引名称和轴标签混为一谈!)
frame.index.names=['key1','key2'] frame.columns.names=['state','color'] frame Out[22]: stateOhioColorado colorGreenRedGreen key1key2 a1012 2345 b1678 291011
由于有了分部的列索引,可以轻松选取列分组:
frame['Ohio'] Out[23]: colorGreenRed key1key2 a101 234 b167 2910
重排分级排序
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
frame.swaplevel('key1','key2') Out[24]: stateOhioColorado colorGreenRedGreen key2key1 1a012 2a345 1b678 2b91011
sortlevel则根据单个级别中的值对数据进行排序。交换级别时,常用得到sortlevel,这样最终结果也是有序的了:
frame.swaplevel(0,1) Out[27]: stateOhioColorado colorGreenRedGreen key2key1 1a012 2a345 1b678 2b91011 #交换级别0,1(也就是key1,key2) #然后对axis=0进行排序 frame.swaplevel(0,1).sortlevel(0) __main__:1:FutureWarning:sortlevelisdeprecated,usesort_index(level=...) Out[28]: stateOhioColorado colorGreenRedGreen key2key1 1a012 b678 2a345 b91011
根据级别汇总统计
有时需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化):
frame.sum(level='key2') Out[29]: stateOhioColorado colorGreenRedGreen key2 16810 2121416 frame.sum(level='color',axis=1) Out[30]: colorGreenRed key1key2 a121 284 b1147 22010
使用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]: abcd 007one0 116one1 225one2 334two0 443two1 552two2 661two3
DataFrame的set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:
frame2=frame.set_index(['c','d']) frame2 Out[34]: ab cd one007 116 225 two034 143 252 361
默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来:
frame.set_index(['c','d'],drop=False) Out[35]: abcd cd one007one0 116one1 225one2 two034two0 143two1 252two2 361two3
reset_index的功能和set_index刚好相反,层次化索引的级别会被转移到列里面:
frame2.reset_index() Out[36]: cdab 0one007 1one116 2one225 3two034 4two143 5two252 6two361
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。