有时候,我们需要重新排列轴上的层级顺序,或者按照特定的层级的值对数据进行排序。 Pandas的swaplevel方法用于这一功能,层级发生变更,但原数据不变。
In [11]: df.swaplevel('key1', 'key2') Out[11]: 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
可以使得结果按照层级进行字典排序:
In [12]: df.sort_index(level=1) Out[12]: 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 In [13]: df.swaplevel(0, 1).sort_index(level=0) Out[13]: 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
sort_index(level=1)
意思是在第2个层级上进行索引的排序。
swaplevel(0, 1)
的意思是将第0层和第1层的行索引进行交换。
使用level参数可以指定你想要在某个特定的轴上进行聚合。
In [15]: df.sum(level='key2') Out[15]: state Ohio Colorado color Green Red Green key2 1 6 8 10 2 12 14 16 In [16]: df.sum(level='color', axis=1) Out[16]: color Green Red key1 key2 a 1 2 1 2 8 4 b 1 14 7 2 20 10
在DataFarme的索引操作中,还有一个比较特殊的场景,就是将一些列转换成层级行索引:
In [17]: df= 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]}) ...: In [18]: df Out[18]: 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 In [19]: df2 = df.set_index(['c','d']) In [20]: df2 Out[20]: 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 In [21]: df.set_index(['c','d'],drop=False) Out[21]: 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 In [22]: df2.reset_index() Out[22]: 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
set_index(['c','d'])
,将c列和d列变成了分层的行索引drop=False
则保留了原来的列数据reset_index
是set_index
的反向操作先看针对Series的操作:
In [3]: tup = [('beijing',2000),('beijing',2019), ...: ('shanghai',2000),('shanghai',2019), ...: ('guangzhou',2000),('guangzhou',2019)] In [4]: values = [10000,100000,6000,60000,4000,40000] In [7]: index = pd.MultiIndex.from_tuples(tup) In [8]: s = pd.Series(values, index=index) In [9]: s Out[9]: beijing 2000 10000 2019 100000 shanghai 2000 6000 2019 60000 guangzhou 2000 4000 2019 40000 dtype: int64 In [10]: s['beijing',2019] Out[10]: 100000 In [11]: s['shanghai'] Out[11]: 2000 6000 2019 60000 dtype: int64 In [15]: s[:,2000] Out[15]: beijing 10000 shanghai 6000 guangzhou 4000 dtype: int64 In [17]: s[s>5000] Out[17]: beijing 2000 10000 2019 100000 shanghai 2000 6000 2019 60000 guangzhou 2019 40000 dtype: int64 In [18]: s[['shanghai','guangzhou']] Out[18]: shanghai 2000 6000 2019 60000 guangzhou 2000 4000 2019 40000 dtype: int64
再看看DataFrame,需要记住和理解的核心是:
In [19]: df = pd.DataFrame(np.arange(12).reshape((4, 3)), ...: index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], ...: columns=[['Ohio', 'Ohio', 'Colorado'], ...: ['Green', 'Red', 'Green']]) ...: In [20]: df Out[20]: Ohio Colorado Green Red Green a 1 0 1 2 2 3 4 5 b 1 6 7 8 2 9 10 11 In [23]: df['Ohio','Colorado'] # 不能这么做,因为列索引分层了 --------------------------------------------------------------------------- KeyError Traceback (most recent call last) In [24]: df[['Ohio','Colorado']] # 这样可以 Out[24]: Ohio Colorado Green Red Green a 1 0 1 2 2 3 4 5 b 1 6 7 8 2 9 10 11 In [25]: df['Ohio','Green'] # 每层提供一个参数 Out[25]: a 1 0 2 3 b 1 6 2 9 Name: (Ohio, Green), dtype: int32 In [26]: df.iloc[:2,:2] # 用隐式索引 Out[26]: Ohio Green Red a 1 0 1 2 3 4 In [28]: df.loc[:,('Ohio','Red')] # 这个比较难理解 Out[28]: a 1 1 2 4 b 1 7 2 10 Name: (Ohio, Red), dtype: int32
另外最后要提醒的是:如果MultiIndex不是有序的索引,那么大多数切片操作都会失败!这时候可以使用前面介绍过的sort_index
方法先排下序。