【问题标题】:Setting values with multiindex in pandas在熊猫中使用多索引设置值
【发布时间】:2016-06-29 14:38:43
【问题描述】:

已经有几个关于 SO 的问题与此相关,最值得注意的是 this one,但是似乎没有一个答案对我有用,而且很多文档链接(尤其是关于 lexsorting)已损坏,所以我会问另一个。

我正在尝试做一些(看似)非常简单的事情。考虑以下 MultiIndexed Dataframe:

import pandas as pd; import random
arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
      ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]

tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.concat([pd.Series(np.random.randn(8), index=index), pd.Series(np.random.randn(8), index=index)], axis=1)

现在我想将0 列中的所有值设置为one 类别中的观察值(例如np.NaN)。我失败了:

df.loc(axis=0)[:, "one"][0] = 1 # setting with copy warning

df.loc(axis=0)[:, "one", 0] = 1

这会产生一个关于键长度超过索引长度的警告,或者一个关于缺乏足够深度的 lexsorting 的警告。

这样做的正确方法是什么?

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    我认为您可以使用loc 和元组来选择MultiIndex0 来选择列:

    import pandas as pd; 
    import random
    arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
          ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
    
    #add for testing
    np.random.seed(0)
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
    df = pd.concat([pd.Series(np.random.randn(8), index=index), pd.Series(np.random.randn(8), index=index)], axis=1)
    
    print df
                         0         1
    first second                    
    bar   one     1.764052 -0.103219
          two     0.400157  0.410599
    baz   one     0.978738  0.144044
          two     2.240893  1.454274
    foo   one     1.867558  0.761038
          two    -0.977278  0.121675
    qux   one     0.950088  0.443863
          two    -0.151357  0.333674
    
    df.loc[('bar', "one"), 0] = 1
    print df
                         0         1
    first second                    
    bar   one     1.000000 -0.103219
          two     0.400157  0.410599
    baz   one     0.978738  0.144044
          two     2.240893  1.454274
    foo   one     1.867558  0.761038
          two    -0.977278  0.121675
    qux   one     0.950088  0.443863
          two    -0.151357  0.333674
    

    如果您需要将级别second 中的所有行设置为one,请使用slice(None)

    df.loc[(slice(None), "one"), 0] = 1
    print df
                         0         1
    first second                    
    bar   one     1.000000 -0.103219
          two     0.400157  0.410599
    baz   one     1.000000  0.144044
          two     2.240893  1.454274
    foo   one     1.000000  0.761038
          two    -0.977278  0.121675
    qux   one     1.000000  0.443863
          two    -0.151357  0.333674
    

    Docs.

    【讨论】:

      猜你喜欢
      • 2021-10-10
      • 2017-05-03
      • 2012-08-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 2019-01-19
      • 2017-05-07
      • 2016-07-06
      相关资源
      最近更新 更多