如何在MultiIndex列上使用Pandas .assign()方法链?

时间:2017-05-11 14:34:48

标签: pandas multi-index method-chaining

对于单级索引列,我将执行以下操作

arrays = [['one', 'two', ]]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.DataFrame(pd.np.random.randn(3, 2), index=['A', 'B', 'C'], columns=index)
print(df)


first   one two
A   0.919921    -1.407321
B   1.100169    -0.927249
C   -0.520308   0.619783

print(df.assign(one=lambda x: x.one * 100))

first   one         two
A       144.950877  0.633516
B       -0.593133   -0.630641
C       -5.661949   -0.738884

现在当我有一个MultiIndex列时,我可以使用.loc访问所需的列,但我无法将其分配给任何内容,因为它会出现错误SyntaxError: keyword can't be an expression

这是一个例子,

arrays = [['bar', 'bar'],
          ['one', 'two']]

tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
df = pd.DataFrame(pd.np.random.randn(3, 2), index=['A', 'B', 'C'], columns=index)

print(df)

first   bar
second  one         two
A       1.119243    0.819455
B       -0.473354   -1.340502
C       0.150403    -0.211392

然而,

df.assign(('bar', 'one')=lambda x: x.loc[:, ('bar', 'one')] * 10)

SyntaxError: keyword can't be an expression

我能做到

df.assign(barOne=lambda x: x.loc[:, ('bar', 'one')] * 10)


first   bar                     barOne
second  one         two 
A       0.433909    0.949701    4.339091
B       0.011486    -1.395144   0.114858
C       -0.289821   2.106951    -2.89821

但这不可取。我想保持我的方法链很好,但也保留MultiIndexed列。

3 个答案:

答案 0 :(得分:1)

如果我正确地读到这个,那就不会那么简单:

原创df:

article

<强>代码:

first        bar
second       one       two
A       0.386729  1.014010
B       0.236824  0.439019
C       0.530020 -0.268751

更新了df(修改列):

df[('bar','one')] *= 10

或者,更新了df(创建新列):

first         bar
second        one       two
A       3.8672946  1.014010
B       2.3682376  0.439019
C       5.3002040 -0.268751

答案 1 :(得分:1)

只是想在同一地方获得更多信息-here's在GitHub上(您!)提出了这个问题,答案是:

  

您可以直接直接编制索引

     

df[('a', 1)] = ...

     

.assign不支持此语法作为其函数调用,其中元组不是有效的标识符。

答案 2 :(得分:0)

使用方法链接的解决方法将为您提供所需的结果。

df = (df.assign(barOne=lambda x: x.loc[:, ('bar', 'one')]*10)
        .rename(columns={'':'barOne'}, level=1)
        .rename(columns={'barOne':'bar'}, level=0)
     )

df

first        bar
second       one       two     barOne
A      -0.016595  0.613149  -0.165947
B      -1.108934 -2.662668 -11.089339
C       0.022323  1.749033   0.223232

df.columns

MultiIndex([('bar',    'one'),
            ('bar',    'two'),
            ('bar', 'barOne')],
           names=['first', 'second'])