如何用Python Pandas按城市和产品计算行间销量差值?
解决方案
1. 统一月份格式并排序
不管month字段的原始格式是字符串、数值还是其他日期格式,先将其转换为Pandas的年月时期类型,既能忽略格式差异,又能保证月份的正确排序:
import pandas as pd # 自动识别多种日期格式,转换为年月时期 df['month'] = pd.to_datetime(df['month'], infer_datetime_format=True).dt.to_period('M') # 按城市、产品、月份排序,确保每组内月份连续 df = df.sort_values(['city', 'product', 'month']).reset_index(drop=True)
2. 分组计算连续月份销量变化
利用Pandas的向量化分组操作,无需遍历行即可高效计算同城市同产品下的销量差值:
# 按city和product分组,用shift()获取上一行销量,计算差值 df['change'] = df.groupby(['city', 'product'])['sold'].apply(lambda x: x - x.shift(1))
核心细节说明
- 性能优势:
groupby和shift()都是Pandas底层优化的向量化操作,处理百万级数据的效率远高于循环遍历。 - 格式兼容:
pd.to_datetime的infer_datetime_format=True参数能自动识别绝大多数常见日期格式(如"202305"、"05/2023"、"May-2023"等),统一转换为时期类型后,完全不受原始格式影响。 - 空值处理:每组的第一行没有前置月份数据,
change列会自动填充NaN,如果需要可以用df['change'] = df['change'].fillna(0)替换为空值。
示例效果
假设原始数据:
| city | product | month | sold |
|---|---|---|---|
| 北京 | 手机 | 2023-03 | 1000 |
| 北京 | 手机 | 202304 | 1200 |
| 上海 | 电脑 | Apr2023 | 800 |
| 上海 | 电脑 | 2023-05 | 950 |
执行代码后得到:
| city | product | month | sold | change |
|---|---|---|---|---|
| 北京 | 手机 | 2023-03 | 1000 | NaN |
| 北京 | 手机 | 2023-04 | 1200 | 200 |
| 上海 | 电脑 | 2023-04 | 800 | NaN |
| 上海 | 电脑 | 2023-05 | 950 | 150 |
内容的提问来源于stack exchange,提问作者Nicola Lepetit
相关产品推荐
相关产品推荐

