python - Pandas - 将列添加到数据框中,根据上个月的项目 ID 查找项目销售额的总和和平均值
问题描述
我有一个名为 grouped_train 的数据框,它按月列出了每个商店中每个商品的销售数量。这是数据框的示例。
date_block_num | item_id | shop_id | item_cnt_month |
---|---|---|---|
0 | 32 | 0 | 6 |
0 | 32 | 5 | 1 |
0 | 26 | 1 | 3 |
0 | 26 | 18 | 9 |
1 | 32 | 46 | 1 |
1 | 26 | 50 | 2 |
有 33 个 date_block_nums 对应不同的月份。我想添加两列,列出上个月/date_block_num 中按 item_id 列出的所有销售额的总和,以及上个月所有 store_id 中该特定 item_id 的销售额平均值,其中 date_block_num == 0 的任何行都应该无。
因此,使用上面的示例 df,输出将如下所示:
date_block_num | item_id | shop_id | item_cnt_month | item_sales_prev_month | mean_item_sales_prev_month |
---|---|---|---|---|---|
0 | 32 | 0 | 6 | 没有任何 | 没有任何 |
0 | 32 | 5 | 1 | 没有任何 | 没有任何 |
0 | 26 | 1 | 3 | 没有任何 | 没有任何 |
0 | 26 | 18 | 9 | 没有任何 | 没有任何 |
1 | 32 | 46 | 1 | 7 | 3.5 |
1 | 26 | 50 | 2 | 12 | 6 |
我已经为 sum_item_prev_month 列编写了一些代码,我认为这些代码可以工作并且可以轻松地更改它以创建平均销售额列,但是我的数据框中有超过 290 万行,我的代码需要多个小时才能运行。诚然,我并不精通 pandas,必须有一些我缺少的矢量化公式来加快计算速度。这是我到目前为止的代码。
sales_by_item_by_month = grouped_train.groupby(['date_block_num', 'item_id'], as_index=False).agg({'item_cnt_month' : 'sum'})
date_block_nums = list(grouped_train['date_block_num'])
item_ids = list(grouped_train['item_id'])
sales_for_item_prev_month = []
for index in range(len(item_ids)):
if date_block_nums[index] == 0:
sales_for_item_prev_month.append(None)
else:
sales = sales_by_item_by_month[(sales_by_item_by_month['item_id'] == item_ids[index]) & (sales_by_item_by_month['date_block_num'] == date_block_nums[index] - 1)]
if len(sales) == 0:
sales_for_item_prev_month.append(0)
else:
sales_for_item_prev_month.append(int(sales['item_cnt_month'].values))
grouped_train['item_sales_prev_month'] = sales_for_item_prev_month
任何建议将不胜感激!
解决方案
假设date_block_num
是顺序的。
尝试计算总和和平均值,groupby agg
然后将 1 递增date_block_num
以将其与下一组对齐:
sum_means = df.groupby(['date_block_num', 'item_id']).agg(
item_sales_prev_month=('item_cnt_month', 'sum'),
mean_item_sales_prev_month=('item_cnt_month', 'mean')
).reset_index()
sum_means['date_block_num'] += 1
sum_means
:
date_block_num item_id item_sales_prev_month mean_item_sales_prev_month
0 1 26 12 6.0
1 1 32 7 3.5
2 2 26 2 2.0
3 2 32 1 1.0
然后merge
回到原来的帧:
df = df.merge(sum_means, on=['date_block_num', 'item_id'], how='left')
df
:
date_block_num item_id shop_id item_cnt_month item_sales_prev_month mean_item_sales_prev_month
0 0 32 0 6 NaN NaN
1 0 32 5 1 NaN NaN
2 0 26 1 3 NaN NaN
3 0 26 18 9 NaN NaN
4 1 32 46 1 7.0 3.5
5 1 26 50 2 12.0 6.0
完整代码:
import pandas as pd
df = pd.DataFrame({
'date_block_num': {0: 0, 1: 0, 2: 0, 3: 0, 4: 1, 5: 1},
'item_id': {0: 32, 1: 32, 2: 26, 3: 26, 4: 32, 5: 26},
'shop_id': {0: 0, 1: 5, 2: 1, 3: 18, 4: 46, 5: 50},
'item_cnt_month': {0: 6, 1: 1, 2: 3, 3: 9, 4: 1, 5: 2}
})
sum_means = df.groupby(['date_block_num', 'item_id']).agg(
item_sales_prev_month=('item_cnt_month', 'sum'),
mean_item_sales_prev_month=('item_cnt_month', 'mean')
).reset_index()
sum_means['date_block_num'] += 1
df = df.merge(sum_means, on=['date_block_num', 'item_id'], how='left')
推荐阅读
- graphql - 无法编辑 Shopify。从草稿订单转换或完成
- python - 如何在 python 中的加权图上实现 Ademic Adar 索引?
- android - 房间读操作很慢
- python - 您应该如何知道可以将哪些参数传递给类?
- graphql - 如何在 Shopify 的 GraphQL 库中按媒体类型对产品图像进行排序?
- javascript - 如何更改网站搜索栏名称?
- java - 如何在 Keycloak 中搜索组内的用户?
- javascript - 在关闭 chrome 中的最后一个选项卡之前显示确认弹出窗口
- javascript - 无效的距离太远了zlib nodejs
- maven - 如何防止 Maven 在更新时将损坏的依赖项加载到本地存储库中