美文网首页
【Chapter 8.1】层次化索引

【Chapter 8.1】层次化索引

作者: 蜘蛛的梦呓 | 来源:发表于2018-05-26 16:14 被阅读0次

    8.1中的操作名

    • join:连接
    • combine:合并
    • reshape:整形

    8.2中的操作名

    • merge:归并
    • concatenate:串联

    8.3中的操作名

    • pivot:旋转
    • stack:堆叠

    【Chapter 8.1】分层索引

    Hierarchical Indexing是pandas中一个重要的特性,能让我们在一个轴(axis)上有多个index levels(索引层级)。它可以让我们在低维格式下处理高维数据。这里给出一个简单的例子,构建一个series,其index是a list of lists:

    data = 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]])
                            
    
    data
    Out[543]: 
    a  1    0.428315
       2   -1.045874
       3   -0.991650
    b  1   -1.418607
       3   -0.295123
    c  1    1.368846
       2   -0.692923
    d  2    2.690562
       3    0.133222
    dtype: float64
    

    其中我们看到的是把MultiIndex作为index(索引)的,美化过后series。

    data.index
    Out[544]: 
    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]])
    

    于这种分层索引对象,partial indexing(部分索引)也是能做到的,这种方法可以让我们简洁地选中数据的一部分:

    data['b']
    Out[545]: 
    1   -1.418607
    3   -0.295123
    dtype: float64
    
    data['b': 'c']
    Out[546]: 
    b  1   -1.418607
       3   -0.295123
    c  1    1.368846
       2   -0.692923
    dtype: float64
    
    data.loc[['b', 'd']]
    Out[547]: 
    b  1   -1.418607
       3   -0.295123
    d  2    2.690562
       3    0.133222
    dtype: float64
    

    selection(选中)对于一个内部层级(inner level)也是可能的:

    data.loc[:, 2]
    Out[548]: 
    a   -1.045874
    c   -0.692923
    d    2.690562
    dtype: float64
    

    分层索引的作用是改变数据的形状,以及做一些基于组的操作(group-based)比如做一个数据透视表(pivot table)。例子,我们可以用unstack来把数据进行重新排列,产生一个DataFrame:

    data.unstack()
    Out[550]: 
              1         2         3
    a  0.428315 -1.045874 -0.991650
    b -1.418607       NaN -0.295123
    c  1.368846 -0.692923       NaN
    d       NaN  2.690562  0.133222
    

    相反的操作是stack:

    data.unstack().stack()
    Out[551]: 
    a  1    0.428315
       2   -1.045874
       3   -0.991650
    b  1   -1.418607
       3   -0.295123
    c  1    1.368846
       2   -0.692923
    d  2    2.690562
       3    0.133222
    dtype: float64
    

    之后的章节会对unstack和stack做更多介绍。

    对于dataframe,任何一个axis(轴)都可以有一个分层索引:

    frame = pd.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[552]: 
         Ohio     Colorado
        Green Red    Green
    a 1     0   1        2
      2     3   4        5
    b 1     6   7        8
      2     9  10       11
    

    每一层级都可以有一个名字(字符串或任何python对象)。如果有的话,这些会显示在输出中:

    frame.index.names = ['key1', 'key2']
    
    frame.columns.names = ['state', 'color']
    
    frame
    Out[555]: 
    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
    

    这里我们要注意区分行标签(row label)中索引的名字'state'和'color'。

    如果想要选中部分列(partial column indexing)的话,可以选中一组列(groups of columns):

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

    MultiIndex能被同名函数创建,而且可以重复被使用;在DataFrame中给列创建层级名可以通过以下方式:

    pd.MultiIndex.from_arrays([['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']],
                          names=['state', 'color'])
    

    1 Reordering and Sorting Levels(重排序和层级排序)

    有时候我们需要在一个axis(轴)上按层级进行排序,或者在一个层级上,根据值来进行排序。swaplevel会取两个层级编号或者名字,并返回一个层级改变后的新对象(数据本身并不会被改变):

    frame.swaplevel('key1', 'key2')
    Out[558]: 
    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,来让结果按指示的层级进行排序:

    frame.sort_index(level=1)
    Out[559]: 
    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
    
    frame.sort_index(level='color') 
    frame.sort_index(level='state') 
    # 这两个语句都会报错
    

    (按照我的理解,level指的是key1和key2,key1是level=0,key2是level=1。可以看到下面的结果和上面是一样的:)

    frame.sort_index(level='key2')
    Out[564]: 
    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
    
    frame.swaplevel(0, 1).sort_index(level=0) # 把key1与key2交换后,按key2来排序
    Out[565]: 
    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
    

    如果index是按词典顺序那种方式来排列的话(比如从外层到内层按a,b,c这样的顺序),在这种多层级的index对象上,数据选择的效果会更好一些。这是我们调用sort_index(level=0) or sort_index()

    2 Summary Statistics by Level (按层级来归纳统计数据)

    在DataFrame和Series中,一些描述和归纳统计数据都是有一个level选项的,这里我们可以指定在某个axis下,按某个level(层级)来汇总。比如上面的DataFrame,我们可以按 行 或 列的层级来进行汇总:

    frame
    Out[566]: 
    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.sum(level='key2')
    Out[567]: 
    state  Ohio     Colorado
    color Green Red    Green
    key2                    
    1         6   8       10
    2        12  14       16
    
    frame.sum(level='color', axis=1)
    Out[568]: 
    color      Green  Red
    key1 key2            
    a    1         2    1
         2         8    4
    b    1        14    7
         2        20   10
    

    3 Indexing with a DataFrame’s columns(利用DataFrame的列来索引)

    把DataFrame里的一列或多列作为行索引(row index)是一件很常见的事;另外,我们可能还希望把行索引变为列。这里有一个例子:

    frame = 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]})
    frame
                          
    Out[569]: 
       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[570]: 
           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
    

    默认删除原先的列,当然我们也可以留着:

    frame.set_index(['c', 'd'], drop=False)
    Out[571]: 
           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[572]: 
         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
    

    相关文章

      网友评论

          本文标题:【Chapter 8.1】层次化索引

          本文链接:https://www.haomeiwen.com/subject/lfvmjftx.html