【问题标题】:Pandas swap columns based on conditionPandas 根据条件交换列
【发布时间】:2016-08-11 16:19:23
【问题描述】:

我有一个如下所示的 pandas 数据框:

    Col1  Col2  Col3
0   A     7     NaN
1   B     16    NaN
1   B     16    15

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

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

但这似乎无法正常工作,并给了我以下信息:

    Col1  Col2  Col3
0   A     NaN   NaN
1   B     NaN   NaN
1   B     NaN   NaN

这里有什么我可能遗漏的吗?

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

    Col1  Col2  Col3
0   A     NaN   7
1   B     NaN   16
1   B     16    15

谢谢

【问题讨论】:

  • Col3 为 None 是什么意思?如果所有元素都是 NaN 还是单个元素就足够了?
  • @ayhan 对于某些行,Col3 的值为 NaN,当这种情况发生时,我想将其与 Col2 交换。我编辑了这个问题,希望现在很清楚。

标签: python pandas swap


【解决方案1】:

您可以使用loc 进行交换:

df.loc[df['Col3'].isnull(), ['Col2', 'Col3']] = df.loc[df['Col3'].isnull(), ['Col3', 'Col2']].values

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

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

null_idx = df['Col3'].isnull()
df.loc[null_idx, 'Col3'] = df['Col2']
df.loc[null_idx, 'Col2'] = np.nan

结果输出:

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

【讨论】:

    【解决方案2】:

    试试这个:(它更快)

    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
    

    【讨论】:

    • 谢谢梅林。知道为什么这种方法比另一种方法更快吗?
    • 我知道,我想知道是什么导致了加速。我也确实赞成你的回答。
    猜你喜欢
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 2018-01-15
    • 2016-02-03
    • 2022-01-13
    • 1970-01-01
    • 2015-10-09
    • 2019-02-12
    相关资源
    最近更新 更多