如何用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)
代码解释
- 获取商品全集:通过
dataset['item_id'].unique()拿到2020年所有出现过的商品ID,确保后续补全时不会遗漏。 - 提取月份:新增
month列,简化按月份分组的逻辑。 - 分组统计:使用
groupby+unstack(fill_value=0)直接统计各月各商品的购买次数,初步填充分组时的缺失值。 - 补全索引:用
reindex指定所有商品ID作为列,缺失的商品自动填充0,保证每个月份的结果包含所有商品。 - 可选优化:将月份数字替换为中文名称,让输出更直观。
替代方案(按月单独处理)
如果需要保持原代码按月单独输出的形式,可以修改每个月份的统计逻辑:
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
相关产品推荐
相关产品推荐

