如何在熊猫中有条件地交换列

ele*_*ora 3 python pandas

我有一个df有 4 列的熊猫数据框 。例如,这是一个玩具示例:

foo1    foo2     foo3  foo4
egg     cheese   2     1
apple   pear     1     3
french  spanish  10    1
Run Code Online (Sandbox Code Playgroud)

列是 foo1、foo2、foo3 和 foo4

我想交换列 foo1 和 foo2,并在 foo3 < foo4 时交换列 foo3 和 foo4。所以结果将是:

foo1     foo2    foo3  foo4
cheese   egg     1     2
apple    pear    1     3
spanish  french  1     10
Run Code Online (Sandbox Code Playgroud)

我可以找到需要交换的行,df[df['foo3'] < df['foo4']] 但如何有效地进行交换。我的数据框很大。

Kar*_*tik 5

您可以找到带有df[df['foo3'] < df['foo4']], yes的行,但是如果您改用布尔系列,则可以轻松实现您的目标:

s = df['foo3'] < df['foo4']
df.loc[s, ['foo1','foo2']] = df.loc[s, ['foo2','foo1']].values
df.loc[s, ['foo3','foo4']] = df.loc[s, ['foo4','foo3']].values
Run Code Online (Sandbox Code Playgroud)

请注意,您需要.values在 RHS 的末尾以防止 Pandas 在列名上对齐,这会破坏目的。


Psi*_*dom 3

您可以使用pandas.Series.where函数根据条件构造新的数据框:

pairs = [('foo1', 'foo2'), ('foo3', 'foo4')]  # construct pairs of columns that need to swapped

df_out = pd.DataFrame() 

# for each pair, swap the values if foo3 < foo4
for l, r in pairs:
    df_out[l] = df[l].where(df.foo3 < df.foo4, df[r])
    df_out[r] = df[r].where(df.foo3 < df.foo4, df[l])

df_out
#     foo1   foo2   foo3  foo4
#0  cheese    egg      1     2
#1   apple   pear      1     3
#2 spanish french      1    10
Run Code Online (Sandbox Code Playgroud)