分层索引进阶

阅读: 4402     评论:0

1.1 重排序和层级排序

有时候,我们需要重新排列轴上的层级顺序,或者按照特定的层级的值对数据进行排序。 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层的行索引进行交换。

1.2 层级的汇总统计

使用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

1.3 使用DataFrame的列进行索引

在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_indexset_index的反向操作

1.4 分层索引的取值与切片

先看针对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,需要记住和理解的核心是:

  • 这是一个分层索引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方法先排下序。


 分层索引 合并连接 

评论总数: 0


点击登录后方可评论