【问题标题】:python pandas add a lower level column to multi_index dataframepython pandas向multi_index数据框添加一个较低级别的列
【发布时间】:2014-10-18 17:52:38
【问题描述】:

有人可以帮我完成这项任务吗? 我通过 unstack() 操作在多级数据框中有数据:

Original df:
Density  Length  Range  Count
  15k    0.60  small    555
  15k    0.60    big     17
  15k    1.80  small    141
  15k    1.80    big     21
  15k    3.60  small    150
  15k    3.60    big     26
  20k    0.60  small   5543
  20k    0.60    big     22
  20k    1.80  small    553
  20k    1.80    big     25
  20k    3.60  small    422
  20k    3.60    big     35

df  = df.set_index(['Density','Length','Range']).unstack('Range')

# After unstack:
                  Count       
Range             big  small
Density Length              
15k     0.60       17    555
        1.80       21    141
        3.60       26    150
20k     0.60       22   5543
        1.80       25    553
        3.60       35    422

现在我尝试在级别 1 中添加一个额外的列。它是小/大的比率。我尝试了以下语法,没有错误但结果不同

#df[:]['ratio']=df['Count']['small']/df['Count']['big'] ## case 1. no error, no ratio
#df['Count']['ratio']=df['Count']['small']/df['Count']['big'] ## case 2. no error, no ratio
#df['ratio']=df['Count']['small']/df['Count']['big'] ## case 3. no error, ratio on column level 0
df['ratio']=df.ix[:,1]/df.ix[:,0]                    ## case 4. no error, ratio on column level 0

#After execution above code, df:
                  Count         ratio
Range             big  small       
Density Length                     
15k     0.60       17    555  32.65
        1.80       21    141   6.71
        3.60       26    150   5.77
20k     0.60       22   5543 251.95
        1.80       25    553  22.12
        3.60       35    422  12.06

我不明白为什么案例 1 和 2 没有显示错误,也没有添加新的比率列。以及为什么在案例 3 和 4 中,比率列位于 0 级,而不是预期的 1 级。还想知道是否有更好/更简洁的方法来实现这一点。案例 4 是我能做的最好的事情,但我不喜欢隐式索引方式(而不是使用名称)来引用列。

谢谢

【问题讨论】:

    标签: python pandas indexing multi-level


    【解决方案1】:

    案例 1

    df[:]['ratio']=df['Count']['small']/df['Count']['big'] 
    

    df[:]df 的副本。它们是不同的对象,每个对象都有自己的底层数据副本:

    In [69]: df[:] is df
    Out[69]: False
    

    所以修改副本对原始df没有影响。因为没有参考 为df[:]维护,对象在赋值后被垃圾回收, 使作业无用。


    案例 2

    df['Count']['ratio']=df['Count']['small']/df['Count']['big'] 
    

    使用chain-indexing。进行分配时避免链式索引。该链接解释了为什么在左侧使用链索引的分配可能不会影响df

    如果你设置了

    pd.options.mode.chained_assignment = 'warn'
    

    然后 Pandas 会警告你不要在分配中使用链索引:

    SettingWithCopyError: 
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead
    
    See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
    

    案例 3

    df['ratio']=df['Count']['small']/df['Count']['big'] 
    

    案例4

    df['ratio']=df.ix[:,1]/df.ix[:,0]
    

    两者都有效,但使用它可以更有效地完成

    df['ratio'] = df['Count','small']/df['Count','big']
    

    这是一个微基准,显示使用 df[tuple_index] 比 链索引:

    In [99]: %timeit df['Count']['small']
    1000 loops, best of 3: 501 µs per loop
    
    In [128]: %timeit df['Count','small']
    100000 loops, best of 3: 8.91 µs per loop
    

    如果你想让ratio成为1级标签,那么你必须告诉Pandas 0级标签是Count。你可以通过分配给df['Count','ratio']来做到这一点:

    In [96]: df['Count','ratio'] = df['Count']['small']/df['Count','big']
    
    # In [97]: df
    # Out[97]: 
    #                Count                  
    # Range            big small       ratio
    # Density Length                        
    # 15k     0.6       17   555   32.647059
    #         1.8       21   141    6.714286
    #         3.6       26   150    5.769231
    # 20k     0.6       22  5543  251.954545
    #         1.8       25   553   22.120000
    #         3.6       35   422   12.057143
    

    【讨论】:

    • 感谢联合国教科文组织。您的回答解决了我对熊猫的许多无知。真的很感激
    • 很好的解释!小评论:对于实际的解决方案,你不能用df[('Count','ratio')]代替df.loc[:, ('Count','ratio')]吗?
    • Joris 评论也有效。到目前为止,我收集到的计算比率的最短和最明确的方法是:df['Count','ratio']=df['Count','small']/df['Count','big'] 谢谢你们俩
    猜你喜欢
    • 1970-01-01
    • 2019-05-26
    • 2016-09-17
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 2018-08-26
    • 2013-04-11
    • 2020-02-01
    相关资源
    最近更新 更多