【问题标题】:Add a value from another column based on the last negative value found for the current row根据为当前行找到的最后一个负值从另一列添加一个值
【发布时间】:2021-11-23 17:36:57
【问题描述】:

我有以下数据框:

data = {'Column A':[400, 522, 633, 744, 150, 140, 119, 744, 150, 400, 390, 315, 744, 150, 400, 522, 500, 633, 744, 204, 215, 150],
    'Column B':[400, 0, 0, 0, -150, 0, 0, 744, 0, -400, 0, 0, -744, 0, -400, 0, 0, -633, 0, 0, 0, 150]}
df = pd.DataFrame(data)

我想要做的是告诉程序逐行执行并将 B 列中最后一个负值的绝对值与当前行的 A 列值进行比较,如果它低 20%,则将其复制到列B. 修改后的 B 列的 Dataframe 如下所示:

data = {'Column A':[400, 522, 633, 744, 150, 140, 119, 744, 150, 400, 390, 315, 744, 150, 400, 522, 500, 633, 744, 204, 215, 150],
    'Column B':[400, 0, 0, 0, -150, 0, 119, 744, 0, -400, 0, 315, -744, 150, -400, 0, 0, -633, 0, 204, 215, 150],
    }

因此,例如在第 6 行中,B 列中的最后一个负值是 -150,因此当您将此值与 A 列中的 140 的值进行比较时,它的绝对值为 150,然后该值不会被复制,因为 140 仍然是在 20% 阈值内,但是在第 7 行,119 比 150 低 20% 以上,因此被复制到 B 列。在第 10 行,最后一个负数变为 -400,因此它将开始使用该值进行比较,然后再次跳过390 但复制 315。

我希望它足够清楚,并提前感谢您的回答。

【问题讨论】:

    标签: python arrays pandas dataframe numpy


    【解决方案1】:

    你可以试试这样的:

    last_value = 0
    for i, n in df.iterrows():
       if n["Column B"] < 0:
           last_value = abs(n["Column B"])
       if n["Column A"] < last_value*0.8:
           df.loc[df.index == i, 'Column B'] = n["Column A"]
    

    【讨论】:

    • 这解决了问题,但由于我的原始数据集有数千行,不使用 If 语句或 for 循环是否有更有效的方法?
    • ..老实说,我没有选择不使用条件语句和循环来至少迭代您的数据框...
    【解决方案2】:

    试试:

    df['New Column B'] = np.where(df['Column B'].ge(0), np.nan, df['Column B'])
    df['New Column B'].ffill(inplace=True)
    condition = df['Column A'] < abs(df['New Column B']*0.8))
    df['New Column B'].mask(condition, df['Column A'], inplace=True)
    condition = df['Column B'].ne(df['New Column B']) & df['New Column B'].ne(df['Column A'])
    df['New Column B'].mask(condition, df['Column B'], inplace=True)
    df['New Column B'] = df['New Column B'].astype(int)
    

    【讨论】:

    • Muhammad 谢谢你,你的解决方案效率更高,但是因为我需要用'新B列'替换'B列'我想问你在这个过程中是否有办法避免使用像“新 B 列”这样的辅助列并简单地在现场覆盖 B 列,以便“新 B 列”成为经过修改的实际 B 列。
    【解决方案3】:

    这是一个带有np.whereffill 之后B 列中的最后一个负值的单行。

    df['newColB'] = ( # you can reassign directly to Column B
        np.where(df['Column A']<0.8*df['Column B'].where(df['Column B']<0).ffill().abs(), 
                 df['Column A'], df['Column B'])
    )
    print(df)
        Column A  Column B  New Column B  newColB
    0        400       400           400      400
    1        522         0             0        0
    2        633         0             0        0
    3        744         0             0        0
    4        150      -150          -150     -150
    5        140         0             0        0
    6        119         0           119      119
    7        744       744           744      744
    8        150         0             0        0
    9        400      -400          -400     -400
    10       390         0             0        0
    11       315         0           315      315
    12       744      -744          -744     -744
    13       150         0           150      150
    14       400      -400          -400     -400
    15       522         0             0        0
    16       500         0             0        0
    17       633      -633          -633     -633
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2022-12-07
      • 2021-05-26
      • 2022-12-03
      • 2022-07-13
      相关资源
      最近更新 更多