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

如何用Pandas按月份分组统计各客户订单数(含0值)

如何用Pandas生成各月份所有客户的订单计数(无订单显示0)

实现步骤及代码

首先准备示例数据(可替换为你的真实数据):

import pandas as pd

# 构建Customer表
customers = pd.DataFrame({'CustomerID': [1, 2, 3]})

# 构建Orders表示例数据
orders = pd.DataFrame({
    'OrderId': [101, 102, 103, 104],
    'CustomerID': [1, 1, 3, 2],
    'Date': ['2023-01-05', '2023-01-15', '2023-02-02', '2023-03-10']
})
# 将Date字段转为日期格式,为后续分组做准备
orders['Date'] = pd.to_datetime(orders['Date'])

接下来生成所有客户与所有订单月份的笛卡尔积,确保每个客户在每个月份都有对应记录:

# 提取Orders表中出现过的所有月份,格式为YYYY-MM的周期类型
order_months = orders['Date'].dt.to_period('M').unique()
# 生成客户ID和月份的笛卡尔积,作为结果的基础框架
customer_month = pd.MultiIndex.from_product(
    [customers['CustomerID'], order_months],
    names=['CustomerID', 'Month']
).to_frame(index=False)

然后统计每个客户每月的订单数,再与基础框架做左连接,空值填充为0:

# 按客户ID和月份分组,统计订单数量
order_counts = orders.groupby(
    [orders['CustomerID'], orders['Date'].dt.to_period('M')]
).size().reset_index(name='OrderCount')

# 左连接保留所有客户-月份组合,无订单的记录填充0
result = pd.merge(
    customer_month,
    order_counts,
    on=['CustomerID', 'Month'],
    how='left'
).fillna(0)
# 将订单数转为整数类型,贴合业务逻辑
result['OrderCount'] = result['OrderCount'].astype(int)

运行后打印结果,格式如下:

CustomerID    Month  OrderCount
0           1  2023-01           2
1           1  2023-02           0
2           1  2023-03           0
3           2  2023-01           0
4           2  2023-02           0
5           2  2023-03           1
6           3  2023-01           0
7           3  2023-02           1
8           3  2023-03           0

补充说明

  • 如果需要包含Orders表中没有的月份(比如全年12个月无论有无订单都要显示),可以手动生成月份范围:
    # 示例:生成2023年1-3月的所有月份
    order_months = pd.period_range(start='2023-01', end='2023-03', freq='M')
    
  • dt.to_period('M')将日期转换为月份周期,比字符串截取更可靠,能避免日期格式不一致的问题
  • 左连接+fillna(0)是实现“无订单显示0”的核心逻辑,确保不会遗漏任何客户-月份组合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:50:31