分层索引

阅读: 4273     评论:0

Pandas提供了Panel和Panel4D对象解决三维和四维数据的处理需求,但更常用的还是分层索引。分层索引是Pandas的重要特性,允许我们在一个轴向上拥有多个索引层级,它提供了一种在更低维度的形式中处理更高维度数据的方式。也就是如何用Series、DataFrame处理三维、四维等等高维度的数据。

比如有下面的数据:

In [168]: s = 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]])

In [169]: s
Out[169]:
a  1    0.283490
   2    0.295529
   3    0.277676
b  1    0.487573
   3    0.091161
c  1    0.285157
   2   -0.806851
d  2   -0.287969
   3   -0.696511
dtype: float64

In [170]: s.index
Out[170]:
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
           labels=[[0, 0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 2, 0, 2, 0, 1, 1, 2]])

MultiIndex就是一个分层索引对象,在打印的时候会进行规整的美化。

下面看下一些基本的操作:

In [171]: s['b']
Out[171]:
1    0.487573
3    0.091161
dtype: float64

In [172]: s['b':'c']
Out[172]:
b  1    0.487573
   3    0.091161
c  1    0.285157
   2   -0.806851
dtype: float64

In [173]: s.loc[['b','d']]
Out[173]:
b  1    0.487573
   3    0.091161
d  2   -0.287969
   3   -0.696511
dtype: float64

In [174]: s.loc['b','d'] # 这样不可以
---------------------------------------------------------------------------
IndexingError                             Traceback (most recent call last)
IndexingError: Too many indexers

In [175]: s.loc['b',1] # 但是这样可以
Out[175]: 0.48757273896298425

In [176]: s.loc[:, 2] # 或者这样
Out[176]:
a    0.295529
c   -0.806851
d   -0.287969
dtype: float64

tup = []

我们还可以这样来生成MultiIndex,请体会它的不同之处:

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) # 利用元组生成MultiIndex

In [8]: sss = pd.Series(values, index=index) # 提供一个MultiIndex作为索引

In [9]: sss
Out[9]:
beijing    2000     10000
           2019    100000
shanghai   2000      6000
           2019     60000
guangzhou  2000      4000
           2019     40000
dtype: int64

更多的创建MultiIndex的方法还有:

  • 从列表:pd.MultiIndex.from_arrays([['a','a','b','b'],[1,2,1,2]])
  • 从元组:pd.MultiIndex.from_tuples([('a',1),('a',2),('b',1),('b',2)])
  • 笛卡儿积:pd.MultiIndex.from_product([['a','b'],[1,2]])
  • 直接构造:pd.MultiIndex(levels=[['a','b'],[1,2]],labels=[[0,0,1,1],[0,1,0,1]])

生成MultiIndex对象后,就可以将这些对象作为参数,在创建Series或者DataFrame时传递给index。或者通过reindex方法更新已有的Series/DataFrame索引。

分层索引在重塑数据和数组透视表中非常重要。比如,我们可以使用unstack方法将数据在DataFrame中重新排列,也就是展开:

In [178]: s.unstack()
Out[178]:
          1         2         3
a  0.283490  0.295529  0.277676
b  0.487573       NaN  0.091161
c  0.285157 -0.806851       NaN
d       NaN -0.287969 -0.696511

In [179]: s.unstack().stack()  # 反操作stack
Out[179]:
a  1    0.283490
   2    0.295529
   3    0.277676
b  1    0.487573
   3    0.091161
c  1    0.285157
   2   -0.806851
d  2   -0.287969
   3   -0.696511
dtype: float64

对于DataFrame对象,每个轴都可以有分层索引,给index或columns提供一个多维数组,就可以分层:

In [3]: 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 [4]: df
Out[4]:
     Ohio     Colorado
    Green Red    Green
a 1     0   1        2
  2     3   4        5
b 1     6   7        8
  2     9  10       11

可以给分层索引自定义名字:

In [5]: df.index.names
Out[5]: FrozenList([None, None])

In [6]: df.index.names = ['key1','key2']

In [7]: df.columns.names
Out[7]: FrozenList([None, None])

In [8]: df.columns.names = ['state','color']

In [9]: df
Out[9]:
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

In [10]: df['Ohio']
Out[10]:
color      Green  Red
key1 key2
a    1         0    1
     2         3    4
b    1         6    7
     2         9   10

 字符串操作 分层索引进阶 

评论总数: 0


点击登录后方可评论