Pandas: query + mul + groupby + cumsum
Pandas: query + mul + groupby + cumsum
我的数据框如下所示:
CUST_NO
ORDER_AMOUNT
PAYT_CODE
IS_PAYMENT_SUCCESSFUL
001
50
OR
1
001
20
IC
0
001
10
IC
1
002
55
IC
1
002
300
MR
1
002
215
MR
0
我想知道客户一直以来成功支付的总金额,特别是来自支付代码 'OR', 'IC'
。数据框按订单日期排序和索引。
预期输出显示在 CUMSUM_OR_IC_SUCCESSFUL
列中:
CUST_NO
ORDER_AMOUNT
PAYT_CODE
IS_PAYMENT_SUCCESSFUL
CUMSUM_OR_IC_SUCCESSFUL
001
50
OR
1
0
001
20
IC
0
50
001
10
IC
1
50
002
55
IC
1
0
002
300
MR
1
55
002
215
MR
0
55
我已经有一些应该可以工作的代码,但它只会保持 运行 直到内核崩溃。
df["CUMSUM_OR_IC_SUCCESSFUL "] = (df.query("PAYT_CODE == ('OR', 'IC')")["IS_PAYMENT_SUCCESSFUL"].mul(df["ORDER_AMOUNT"])
.groupby(df["CUST_NO"])
.transform(lambda x: x.cumsum().shift().fillna(0))
)
感谢任何帮助!
回答
agg = df.groupby("CUST_NO").apply(lambda x:(x["ORDER_AMOUNT"] * x["PAYT_CODE"].isin(["IC", "OR"]) * x["IS_PAYMENT_SUCCESSFUL"]).cumsum())
df["CUMSUM_OR_IC_SUCCESSFUL"] = agg.to_numpy()
输出
虽然和你预期的不一样,但我还是猜测你的输出table有一点点错误。
如果你想 shift
CUMSUM_OR_IC_SUCCESSFUL
有一个位置,使用 agg.shift().to_numpy()
CUST_NO ORDER_AMOUNT ... IS_PAYMENT_SUCCESSFUL CUMSUM_OR_IC_SUCCESSFUL
0 1 50 ... 1 50
1 1 20 ... 0 50
2 1 10 ... 1 60
3 2 55 ... 1 55
4 2 300 ... 1 55
5 2 215 ... 0 55
说明
apply
将为每个 group
运行
经过一些试验,这个成功了:
df["CUMSUM_GUARANTEED_SUCCESSFUL"] = df["ORDER_AMOUNT"].mul(df["PAYMENT_SUCCESSFUL"]).mul(df["PAYT_CODE"].isin(['IC', 'OC'])).groupby(df["CUST_NO"]).transform(lambda x: x.cumsum().shift().fillna(0))}
我的数据框如下所示:
CUST_NO | ORDER_AMOUNT | PAYT_CODE | IS_PAYMENT_SUCCESSFUL |
---|---|---|---|
001 | 50 | OR | 1 |
001 | 20 | IC | 0 |
001 | 10 | IC | 1 |
002 | 55 | IC | 1 |
002 | 300 | MR | 1 |
002 | 215 | MR | 0 |
我想知道客户一直以来成功支付的总金额,特别是来自支付代码 'OR', 'IC'
。数据框按订单日期排序和索引。
预期输出显示在 CUMSUM_OR_IC_SUCCESSFUL
列中:
CUST_NO | ORDER_AMOUNT | PAYT_CODE | IS_PAYMENT_SUCCESSFUL | CUMSUM_OR_IC_SUCCESSFUL |
---|---|---|---|---|
001 | 50 | OR | 1 | 0 |
001 | 20 | IC | 0 | 50 |
001 | 10 | IC | 1 | 50 |
002 | 55 | IC | 1 | 0 |
002 | 300 | MR | 1 | 55 |
002 | 215 | MR | 0 | 55 |
我已经有一些应该可以工作的代码,但它只会保持 运行 直到内核崩溃。
df["CUMSUM_OR_IC_SUCCESSFUL "] = (df.query("PAYT_CODE == ('OR', 'IC')")["IS_PAYMENT_SUCCESSFUL"].mul(df["ORDER_AMOUNT"])
.groupby(df["CUST_NO"])
.transform(lambda x: x.cumsum().shift().fillna(0))
)
感谢任何帮助!
回答
agg = df.groupby("CUST_NO").apply(lambda x:(x["ORDER_AMOUNT"] * x["PAYT_CODE"].isin(["IC", "OR"]) * x["IS_PAYMENT_SUCCESSFUL"]).cumsum())
df["CUMSUM_OR_IC_SUCCESSFUL"] = agg.to_numpy()
输出
虽然和你预期的不一样,但我还是猜测你的输出table有一点点错误。
如果你想 shift
CUMSUM_OR_IC_SUCCESSFUL
有一个位置,使用 agg.shift().to_numpy()
CUST_NO ORDER_AMOUNT ... IS_PAYMENT_SUCCESSFUL CUMSUM_OR_IC_SUCCESSFUL
0 1 50 ... 1 50
1 1 20 ... 0 50
2 1 10 ... 1 60
3 2 55 ... 1 55
4 2 300 ... 1 55
5 2 215 ... 0 55
说明
apply
将为每个 group
经过一些试验,这个成功了:
df["CUMSUM_GUARANTEED_SUCCESSFUL"] = df["ORDER_AMOUNT"].mul(df["PAYMENT_SUCCESSFUL"]).mul(df["PAYT_CODE"].isin(['IC', 'OC'])).groupby(df["CUST_NO"]).transform(lambda x: x.cumsum().shift().fillna(0))}