Pandas根据条件交换列

dag*_*g3r 8 python swap pandas

我有一个像下面这样的pandas数据帧:

    Col1  Col2  Col3
0   A     7     NaN
1   B     16    NaN
1   B     16    15
Run Code Online (Sandbox Code Playgroud)

我想要做的是将Col2与Col3交换Col3的值NaN.根据SO上的其他帖子和答案,到目前为止我有这个代码:

df[['Col2', 'Col3']] = df[['Col3', 'Col2']].where(df[['Col3']].isnull())
Run Code Online (Sandbox Code Playgroud)

但这似乎没有正常工作,并给我以下内容:

    Col1  Col2  Col3
0   A     NaN   NaN
1   B     NaN   NaN
1   B     NaN   NaN
Run Code Online (Sandbox Code Playgroud)

有什么我可能会在这里失踪?

更新:我想要的输出如下:

    Col1  Col2  Col3
0   A     NaN   7
1   B     NaN   16
1   B     16    15
Run Code Online (Sandbox Code Playgroud)

谢谢

roo*_*oot 12

你可以loc用来做交换:

df.loc[df['Col3'].isnull(), ['Col2', 'Col3']] = df.loc[df['Col3'].isnull(), ['Col3', 'Col2']].values
Run Code Online (Sandbox Code Playgroud)

请注意,.values确保交换正确完成是必需的,否则Pandas会尝试根据索引和列名进行对齐,并且不会发生交换.

如果您觉得代码更清晰,您也可以单独重新分配每一行:

null_idx = df['Col3'].isnull()
df.loc[null_idx, 'Col3'] = df['Col2']
df.loc[null_idx, 'Col2'] = np.nan
Run Code Online (Sandbox Code Playgroud)

结果输出:

  Col1  Col2  Col3
0    A   NaN   7.0
1    B   NaN  16.0
2    B  16.0  15.0
Run Code Online (Sandbox Code Playgroud)


Mer*_*lin 5

试试这个:(更快)

df["Col3"], df["Col2"] = np.where(df['Col3'].isnull(), [df["Col2"], df["Col3"]], [df["Col3"], df["Col2"] ])
df

     Col1  Col2  Col3
0    A   NaN   7.0
1    B   NaN  16.0
1    B  16.0  15.0


    %timeit df.loc[df['Col3'].isnull(), ['Col2', 'Col3']] = df.loc[df['Col3'].isnull(), ['Col3', 'Col2']].values
100 loops, best of 3: 2.68 ms per loop


    %timeit df["Col3"], df["Col2"] = np.where(df['Col3'].isnull(), [df["Col2"], df["Col3"]], [df["Col3"], df["Col2"] ])
1000 loops, best of 3: 592 µs per loop
Run Code Online (Sandbox Code Playgroud)