如何用Python Pandas按日期区间统计各产品销量?
用Pandas按日期区间分组统计产品销量的解决方案
别担心,咱们一步步来搞定这个需求,代码都是入门级的,每一步我都会解释清楚。
第一步:明确需求逻辑
首先要搞清楚:这里的“1-3天”“4-7天”是指每个产品从第一次销售开始算起的相对天数——比如某产品第一次卖是8月1日,那8月1-3日的销售属于「1-3天」区间,8月4-7日属于「4-7天」,以此类推。
第二步:编写代码实现
1. 导入必要的库
首先导入pandas,这是Python处理表格数据的核心工具:
import pandas as pd
2. 准备/读取数据
如果你的数据存在CSV文件里,用pd.read_csv("你的文件路径.csv")读取即可;这里先模拟你的示例数据集:
# 模拟示例数据 data = { "PRODUCT_ID": ["0E4234", "0E4234", "0E4234", "0E4234", "0E4234", "0G2342", "0G2342", "0G2342", "0G2342", "0G2342", "0G2342"], "DATE_LOCATION": ["01-08-16 0:00", "02-08-16 0:00", "04-08-16 0:00", "08-08-16 0:00", "09-08-16 0:00", "02-08-16 0:00", "03-08-16 0:00", "06-08-16 0:00", "09-08-16 0:00", "11-08-16 0:00", "15-08-16 0:00"], "Sold": [2,7,3,1,2,1,2,1,1,3,3] } df = pd.DataFrame(data)
3. 数据预处理:转换日期格式+排序
首先把DATE_LOCATION列的字符串转换成pandas能识别的日期类型,然后按产品ID和日期排序,确保每个产品的销售记录是按时间顺序排列的:
# 转换日期格式,注意你的日期是DD-MM-YY HH:MM格式,所以指定format参数 df["DATE_LOCATION"] = pd.to_datetime(df["DATE_LOCATION"], format="%d-%m-%y %H:%M") # 按产品ID和日期升序排序 df = df.sort_values(by=["PRODUCT_ID", "DATE_LOCATION"])
4. 计算每个产品的相对天数
对每个产品,计算每条记录的日期与该产品第一次销售日期的天数差,然后加1(这样第一次销售的日期就对应「第1天」):
# 分组计算每个产品的最早销售日期,给每条记录都添加上这个值 df["first_sale_date"] = df.groupby("PRODUCT_ID")["DATE_LOCATION"].transform("min") # 计算相对天数:当前日期与最早日期的天数差 + 1 df["relative_day"] = (df["DATE_LOCATION"] - df["first_sale_date"]).dt.days + 1
5. 定义日期区间并分组统计销量
用pd.cut()函数把相对天数分成你需要的区间,然后按产品ID和区间分组,计算每个区间的销量总和:
# 定义区间边界:0-3, 3-7,7-15,15+(right=False表示左闭右开,比如1-3天包含1、2、3) bins = [0, 3, 7, 15, float("inf")] # 对应区间的标签 labels = ["1-3", "4-7", "8-15", ">16"] # 给每条数据打上对应的区间标签 df["Days"] = pd.cut(df["relative_day"], bins=bins, labels=labels, right=False) # 分组求和:按产品ID和区间分组,计算Sold的总和 result = df.groupby(["PRODUCT_ID", "Days"])["Sold"].sum().reset_index()
6. 整理成你期望的输出格式
如果想把区间作为列(和你示例的宽表格式一致),可以用pivot()函数转换:
# 转换成宽表,空值用0填充(表示该区间没有销量) wide_result = result.pivot(index="PRODUCT_ID", columns="Days", values="Sold").fillna(0).reset_index() # 调整列名顺序(可选,让输出和示例更匹配) wide_result = wide_result[["PRODUCT_ID", "1-3", "4-7", "8-15", ">16"]]
查看最终结果
运行完上面的代码后,打印结果即可:
print("长表格式结果(适合后续分析):") print(result) print("\n宽表格式结果(和你示例一致):") print(wide_result)
关键知识点小提示
pd.to_datetime():必须把字符串日期转换成日期类型,才能进行天数差的计算groupby().transform():可以给同一分组的所有行添加分组级别的统计值(比如这里的最早销售日期)pd.cut():专门用来把连续数值分成离散区间,是处理这类分组需求的利器pivot():快速实现长表和宽表的转换,让结果更符合展示需求
内容的提问来源于stack exchange,提问作者san
相关产品推荐
相关产品推荐

