gpt4 book ai didi

python - Pandas groupby 变换累积条件

转载 作者:行者123 更新时间:2023-12-03 17:10:26 25 4
gpt4 key购买 nike

我有一个包含许多产品 ID 和 iso_codes 的大表:总共 200 万行。所以答案应该(如果可能)也考虑到内存问题,我有 16 GB 内存。

我想看对于每个 (id, iso_code) 组合 什么退回的商品数量在购买日期之前 在行 (如此累积),但有一个问题 :
我只想计算之前销售中发生的退货,其中 return_date 在我正在查看的 buy_date 之前。

我已添加 列 items_returned 例如:这是应该计算的列。
思路如下:
在销售的那一刻,我只能计算已经发生的退货,而不是将来会发生的退货。
我尝试了 df.groupby(['id', 'iso_code']).transform(np.cumsum) 的组合和 .transform(lambda x: only count returns that happened before my buy_date) ,但不知道如何做 .groupby.transform(np.cumsum)这些特殊条件适用。
购买元素的类似问题,我只计算比我的buy_date小的天数的累计元素。
希望您能够帮助我。
结果表示例:

+-------+------+------------+----------+------------+---------------+----------------+------------------+
| row | id | iso_code | return | buy_date | return_date | items_bought | items_returned |
|-------+------+------------+----------+------------+---------------+----------------+------------------|
| 0 | 177 | DE | 1 | 2019-05-16 | 2019-05-24 | 0 | 0 |
| 1 | 177 | DE | 1 | 2019-05-29 | 2019-06-03 | 1 | 1 |
| 2 | 177 | DE | 1 | 2019-10-27 | 2019-11-06 | 2 | 2 |
| 3 | 177 | DE | 0 | 2019-11-06 | None | 3 | 2 |
| 4 | 177 | DE | 1 | 2019-11-18 | 2019-11-28 | 4 | 3 |
| 5 | 177 | DE | 1 | 2019-11-21 | 2019-12-11 | 5 | 3 |
| 6 | 177 | DE | 1 | 2019-11-25 | 2019-12-06 | 6 | 3 |
| 7 | 177 | DE | 0 | 2019-11-30 | None | 7 | 4 |
| 8 | 177 | DE | 1 | 2020-04-30 | 2020-05-27 | 8 | 6 |
| 9 | 177 | DE | 1 | 2020-04-30 | 2020-09-18 | 8 | 6 |
+-------+------+------------+----------+------------+---------------+----------------+------------------+
示例代码:
import pandas as pd
from io import StringIO

df_text = """
row id iso_code return buy_date return_date
0 177 DE 1 2019-05-16 2019-05-24
1 177 DE 1 2019-05-29 2019-06-03
2 177 DE 1 2019-10-27 2019-11-06
3 177 DE 0 2019-11-06 None
4 177 DE 1 2019-11-18 2019-11-28
5 177 DE 1 2019-11-21 2019-12-11
6 177 DE 1 2019-11-25 2019-12-06
7 177 DE 0 2019-11-30 None
8 177 DE 1 2020-04-30 2020-05-27
9 177 DE 1 2020-04-30 2020-09-18
"""

df = pd.read_csv(StringIO(df_text), sep='\t', index_col=0)

df['items_bought'] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 8]
df['items_returned'] = [0, 1, 2, 2, 3, 3, 3, 4, 6, 6]

最佳答案

这似乎需要交叉合并:

(df[['id','iso_code', 'buy_date']].reset_index()
.merge(df[['id','iso_code', 'return','return_date','buy_date']], on=['id','iso_code'])
.assign(items_returned=lambda x: x['return_date'].lt(x['buy_date_x'])*x['return'],
items_bought=lambda x: x['buy_date_y'].lt(x['buy_date_x']))
.groupby('row')[['items_bought','items_returned']].sum()
)
输出:
     items_bought  items_returned
row
0 0 0
1 1 1
2 2 2
3 3 2
4 4 3
5 5 3
6 6 3
7 7 4
8 8 6
9 8 6

更新 对于较大的数据,由于内存要求,交叉合并并不理想。然后我们可以做一个 groupby()所以我们只合并较小的组:
def myfunc(df):
return (df[['id','iso_code', 'buy_date']].reset_index()
.merge(df[['id','iso_code', 'return','return_date','buy_date']], on=['id','iso_code'])
.assign(items_returned=lambda x: x['return_date'].lt(x['buy_date_x'])*x['return'],
items_bought=lambda x: x['buy_date_y'].lt(x['buy_date_x']))
.groupby('row')[['items_bought','items_returned']].sum()
)

df.groupby(['id','iso_code']).apply(myfunc).reset_index(level=[0,1], drop=True)
你会得到相同的输出:
     items_bought  items_returned
row
0 0 0
1 1 1
2 2 2
3 3 2
4 4 3
5 5 3
6 6 3
7 7 4
8 8 6
9 8 6

关于python - Pandas groupby 变换累积条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64373081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com