在pandas中使用multiindex设置值

Nil*_*dat 5 python multi-index pandas

关于SO的问题已经有几个问题,尤其是这个问题,但是没有一个答案似乎对我有用,并且很多文档链接(特别是关于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)
Run Code Online (Sandbox Code Playgroud)

现在我想将列中的所有值设置0为某个值(比方说np.NaN),以便在类别中进行观察one.我失败了:

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

df.loc(axis=0)[:, "one", 0] = 1
Run Code Online (Sandbox Code Playgroud)

这或者产生关于键的长度超过索引长度的警告,或者关于缺少lexsorting到足够深度的警告.

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

jez*_*ael 5

我认为您可以使用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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

如果需要将所有行设置为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
Run Code Online (Sandbox Code Playgroud)

文件