簡體   English   中英

如何在 Pandas 中鏈接 MultiIndex 列的分配?

[英]How can I chain assignments of MultiIndex columns in Pandas?

對於單級索引列,我會執行以下操作

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 列。

如果我沒看錯的話,它會不會像這樣簡單:

原始df:

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

代碼:

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

或者,更新 df (創建新列):

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

first        bar
second       one       two       new
A       0.386729  1.014010  3.867295
B       0.236824  0.439019  2.368238
C       0.530020 -0.268751  5.300204

只是為了在同一個地方獲得更多信息 -這是在 GitHub 上提出的這個問題(由你!),回復是:

你可以簡單地直接索引

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

.assign不能支持此語法作為其函數調用,其中元組不是有效標識符。

這種使用方法鏈接的解決方法會給你你想要的結果。

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'])

使用.join() (一個LEFT JOIN ):

df.drop(columns=('bar', 'one')).join(df[('bar', 'one')] * 10)

結果:

first   bar
second  two         one
A       0.949701    4.339091
B       -1.395144   0.114858
C       2.106951    -2.89821

如果df尚未分配,它仍然可以通過用.pipe()包裝來鏈接:

(...).pipe(
    lambda df: df.drop(columns=('bar', 'one')).join(df[('bar', 'one')] * 10)
)

同樣的結果也可以通過.append()獲得:

df.T.drop(('bar', 'one')).append(df[('bar', 'one')] * 10).T

自 1.4.0 版起已棄用,取而代之的是pd.concat() (一個OUTER JOIN ):

pd.concat(axis='columns', objs=[
    df.drop(columns=[('bar', 'one')]), df[('bar', 'one')] * 10,
])

並且在任何情況下,一個完全可以是.rename() MultiIndex 列的過程:

(df[('bar', 'one')] * 10).rename(('baz', 'ten'))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM