You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas在聚合表中填充空值,展示月度未购商品的0值

解决CSV数据中2020年各月商品购买次数统计(含未购买商品0值显示)

问题背景

需要统计purchases.csv中2020年每个月各item_id的购买次数,要求当月未被购买的item_id显示为0,但现有代码仅能输出当月有购买记录的item_id,无法展示0值。

原代码

#Reading the dataset
data = pd.read_csv('purchases.csv')
df = pd.DataFrame(data)


#Filtering the data
df['date']=pd.to_datetime(df['date'])
dataset=df[df['date'].dt.year == 2020]

#january
# Select DataFrame rows between two dates
januaryFilter = (dataset['date'] > '2020-01-01') & (dataset['date'] <= '2020-01-31')
january = dataset.loc[januaryFilter]
jan = pd.crosstab(january['item_id'], januaryFilter)
print(jan)

#february
# Select DataFrame rows between two dates
februaryFilter = (dataset['date'] > '2020-02-01') & (dataset['date'] <= '2020-02-28')
february = dataset.loc[februaryFilter]
feb = pd.crosstab(february['item_id'], februaryFilter)
print(feb)

数据集

session_id,item_id,date
3,15085,2020-12-18 21:26:47.986
13,18626,2020-03-13 19:36:15.507
18,24911,2020-08-26 19:20:32.049
19,12534,2020-11-02 17:16:45.92
24,13226,2020-02-26 18:27:44.114
28,26394,2020-05-18 12:52:09.764
31,8345,2021-04-20 19:46:42.594
36,14532,2020-06-21 10:33:22.535
42,11784,2021-03-01 15:17:04.264
44,4028,2020-11-27 20:46:08.951
48,24022,2020-04-15 17:29:15.414
49,2011,2020-05-01 12:34:29.86
52,12556,2020-03-21 11:49:07.324
75,28057,2020-05-24 17:27:54.288
77,4243,2020-09-20 21:37:20.838
107,4016,2020-01-15 06:07:23.177
108,18532,2020-06-06 17:25:15.508
113,21107,2021-05-05 14:15:07.278
115,25976,2021-05-27 10:24:05.043
119,434,2020-10-11 06:32:22.085
124,3732,2020-05-18 11:04:15.42
127,25117,2020-01-15 15:17:43.659
140,23502,2021-04-28 13:45:31.202

解决方案

核心思路是先获取2020年所有出现过的item_id全集,再按月统计每个item_id的购买次数,最后用全集索引补全未出现的item_id并填充0值。

优化后代码(批量处理所有月份)

import pandas as pd

# 读取数据并处理日期
df = pd.read_csv('purchases.csv')
df['date'] = pd.to_datetime(df['date'])

# 筛选2020年数据
dataset = df[df['date'].dt.year == 2020]

# 获取2020年所有唯一的item_id
all_item_ids = dataset['item_id'].unique()

# 提取月份列
dataset['month'] = dataset['date'].dt.month

# 按月份和item_id分组统计购买次数,缺失值填充0
monthly_counts = dataset.groupby(['month', 'item_id']).size().unstack(fill_value=0)

# 用所有item_id补全索引,确保每个月份包含所有商品
monthly_counts = monthly_counts.reindex(columns=all_item_ids, fill_value=0)

# 重命名月份索引为中文(可选,提升可读性)
monthly_counts.index = ['1月', '2月', '3月', '4月', '5月', '6月', '8月', '9月', '10月', '11月', '12月']

# 输出结果
print(monthly_counts)

代码解释

  1. 获取商品全集:通过dataset['item_id'].unique()拿到2020年所有出现过的商品ID,确保后续补全时不会遗漏。
  2. 提取月份:新增month列,简化按月份分组的逻辑。
  3. 分组统计:使用groupby+unstack(fill_value=0)直接统计各月各商品的购买次数,初步填充分组时的缺失值。
  4. 补全索引:用reindex指定所有商品ID作为列,缺失的商品自动填充0,保证每个月份的结果包含所有商品。
  5. 可选优化:将月份数字替换为中文名称,让输出更直观。

替代方案(按月单独处理)

如果需要保持原代码按月单独输出的形式,可以修改每个月份的统计逻辑:

import pandas as pd

df = pd.read_csv('purchases.csv')
df['date'] = pd.to_datetime(df['date'])
dataset = df[df['date'].dt.year == 2020]
all_item_ids = dataset['item_id'].unique()

# 1月统计
january = dataset[dataset['date'].dt.month == 1]
jan_counts = january['item_id'].value_counts().reindex(all_item_ids, fill_value=0)
print("1月购买次数:")
print(jan_counts)

# 2月统计
february = dataset[dataset['date'].dt.month == 2]
feb_counts = february['item_id'].value_counts().reindex(all_item_ids, fill_value=0)
print("\n2月购买次数:")
print(feb_counts)

这种方式每个月份单独处理,用value_counts统计次数后,通过reindex补全所有商品ID并填充0。


内容的提问来源于stack exchange,提问作者reallilpunch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:31:09