根据另一列numpy中的阈值和条件计算累积和

2024-10-01 04:52:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据框,我想根据两个条件计算累计总和:

  • 表中已存在的第一个布尔值
  • 还有一个固定的阈值,用于检查累计总和

我已经成功地获得了第一名或第二名,但我发现很难将两者结合起来

我第一次使用groupby

df['group'] = np.cumsum((df['IsSuccess'] != df['IsSuccess'].shift(1)))
df['SumSale'] = df[['Sale', 'group']].groupby('group').cumsum()

第二次从Pyfunc开始

sumlm = np.frompyfunc(lambda a,b: b if (a+b>5) else a+b, 2, 1)
df['SumSale'] = sumlm.accumulate(df['Sale'], dtype=object)

我的df是,SumSale是我想要的结果

df2 = pd.DataFrame({'Sale': [10, 2, 2, 1, 3, 2, 1, 3, 5, 5],
                 'IsSuccess': [False, True, False, False, True, False, True, False, False, False],
                 'SumSaleExpected': [10, 12, 2, 3, 6, 2, 3, 6, 11, 16]})

所以总结一下,我想在总和超过5并且行IsSuccess为真时开始累积总和。如果可能的话,我想避免for循环

谢谢你的帮助


Tags: 数据falsetruedfnpgroup阈值sale
2条回答

您可以通过考虑两个条件中的cumsum()来修改group方法以考虑这两个条件:

cond1 = df.Sale.cumsum().gt(5).shift().bfill()
cond2 = df.IsSuccess.shift().bfill()

df['group'] = (cond1 & cond2).cumsum()

既然group解释了这两种情况,您可以在这些伪组中直接cumsum()

df['SumSale'] = df.groupby('group').Sale.cumsum()

#    Sale  IsSuccess  group  SumSale
# 0     1      False      0        1
# 1     2       True      0        3
# 2     3      False      0        6
# 3     2      False      0        8
# 4     4       True      0       12
# 5     3      False      1        3

我希望我正确理解了你的问题。当累计销售总额大于5且IsSuccess==True时,此示例将减去必要值(“重置”):

df["SumSale"] = df["Sale"].cumsum()

# "reset" when SumSale>5 and IsSuccess==True
m = df["SumSale"].gt(5) & df["IsSuccess"].eq(True)
df.loc[m, "to_remove"] = df["SumSale"]
df["to_remove"] = df["to_remove"].ffill().shift().fillna(0)
df["SumSale"] -= df["to_remove"]

df = df.drop(columns="to_remove")

print(df)

印刷品:

   Sale  IsSuccess  SumSale
0     1      False      1.0
1     2       True      3.0
2     3      False      6.0
3     2      False      8.0
4     4       True     12.0
5     3      False      3.0
6     5       True      8.0
7     5      False      5.0

编辑:

def fn():
    sale, success = yield
    cum = sale
    while True:
        sale, success = yield cum
        if success and cum > 5:
            cum = sale
        else:
            cum += sale


s = fn()
next(s)
df["ss"] = df["IsSuccess"].shift()
df["SumSale"] = df.apply(lambda x: s.send((x["Sale"], x["ss"])), axis=1)
df = df.drop(columns="ss")
print(df)

印刷品:

   Sale  IsSuccess  SumSaleExpected  SumSale
0    10      False               10       10
1     2       True               12       12
2     2      False                2        2
3     1      False                3        3
4     3       True                6        6
5     2      False                2        2
6     1       True                3        3
7     3      False                6        6
8     5      False               11       11
9     5      False               16       16

相关问题 更多 >