【问题标题】:Updating a column if condition is met with pandas如果熊猫满足条件,则更新列
【发布时间】:2021-04-30 15:08:06
【问题描述】:

我有一个数据框要处理,我正在执行几项检查。

我正在检查“A”、“B”和“C”列下的重复值是否在 D 列下呈现相同的数字但符号相反。

A B C D E
1111 AAA 123 0.01 comment to be replaced
2222 BBB 456 5 comment to be replaced
3333 CCC 789 10 don't do anything
1111 AAA 123 -0.01 comment to be replaced
2222 BBB 456 -5 comment to be replaced
3333 CCC 789 -9 don't do anything

请在下面查看我的代码。当我尝试替换“E”列下的评论时,它不起作用。我确定我做错了什么。 我完全意识到我没有以最有效的方式编写代码,我仍然是新手。您能否帮助我以更有效的方式来实现这一目标,并且出于好奇,如果我决定继续使用这种“非高效”方式,如何实现这一目标?

谢谢。

for i in range(0, len(df)-1):
    for j in range(i+1, len(df)):
        if (df['A'][i] == df['A'][j]) & (df['B'][i] == df['B'][j]) & (df['C'][i] == df['C'][j]) & (df['D'][i] + df['D'][j] = 0) :
            df['E'][i] = 'it works!'

【问题讨论】:

  • A, B, C 的每个唯一值是否可以多于/少于两行?
  • 感谢您的评论@ShubhamSharma。是的,如果有更多/更少的列,评论会有所不同。
  • 请不要编辑问题以使现有答案无效。最好换一个新的。阅读this 和相关帖子,了解更多关于良好做法的信息
  • @DaniB 请考虑添加一个新问题并回滚您当前的编辑,因为您的最新编辑完全使现有答案无效。

标签: python pandas dataframe


【解决方案1】:

我们可以 group 列上的数据框 ABC 以及列中的一系列绝对值 D 然后 transformD 使用 sum (因为如果符号相反,那么总和必须为零)以检查是否存在具有相同大小但符号相反的对

df['E'] = df.groupby(['A', 'B', 'C', df['D'].abs()])['D'].transform('sum').eq(0) 

      A    B    C      D      E
0  1111  AAA  123   0.01   True
1  2222  BBB  456   5.00   True
2  3333  CCC  789  10.00  False
3  1111  AAA  123  -0.01   True
4  2222  BBB  456  -5.00   True
5  3333  CCC  789  -9.00  False

【讨论】:

  • 太棒了!如果我还想更新“E”列下满足条件的行的注释怎么办?
  • @DaniB 我们可以使用np.where。请查看df['E'] = np.where(df['E'], 'it works', 'it doesnt work')
  • 如果明确只能有 1 个正值和 1 个负值,这个答案非常聪明。但是,如果条目不均匀,或者有多个 A、B、C 组合,它就会变得不稳定。例如。尝试将2222 BBB 456 -1 comment to be replaced添加到您的示例中。
  • 感谢您对@Andreas 的评论,但恕我直言,即使输入不均匀,它仍然可以工作。因为这里我们对列 D 的绝对值进行了额外分组,所以不均匀的条目不会找到一对,并且在任何情况下转换的结果都不会等于零。
  • @Andreas 说得好。我的下一个目标是找到加在一起(满足条件)的对给出不匹配的数量。
【解决方案2】:

这适用于您在 E 中有不止一对,或者如果有 1 个正数和多个负数,反之亦然。

import pandas as pd
import numpy as np

df_1 = df[df['D'] >= 0].copy().reset_index()
df_2 = df[df['D'] < 0].copy().reset_index()
df_2['D'] = -df_2['D']

indexes = df_1.merge(df_2, on=['A', 'B', 'C', 'D'], how='inner')[['index_x', 'index_y']].values.tolist()
indexes = [item for sublist in indexes for item in sublist]

df['E_new'] = np.where(df.index.isin(indexes), 'new comment', df['E'])

print(df)

#       A    B    C      D                       E              E_new
# 0  1111  AAA  123   0.01  comment to be replaced        new comment
# 1  2222  BBB  456   5.00  comment to be replaced        new comment
# 2  3333  CCC  789  10.00       don't do anything  don't do anything
# 3  1111  AAA  123  -0.01  comment to be replaced        new comment
# 4  2222  BBB  456  -5.00  comment to be replaced        new comment
# 5  3333  CCC  789  -9.00       don't do anything  don't do anything

【讨论】:

    猜你喜欢
    • 2019-09-06
    • 1970-01-01
    • 2019-02-15
    • 2016-08-22
    • 2014-02-11
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多