原数据如下:
匹配日期 分类 品牌 销售金额 最后一天
0 2023-01-01 跨境贸易 A 1000 2023-01-31
1 2023-02-01 跨境贸易 A 2000 2023-02-28
2 2023-04-01 跨境贸易 A 4000 2023-04-30
3 2023-05-01 跨境贸易 A 5000 2023-05-31
4 2023-06-01 跨境贸易 A 6000 2023-06-30
5 2023-07-01 跨境贸易 A 7000 2023-07-31
6 2023-10-01 跨境贸易 A 10000 2023-10-31
7 2023-11-01 跨境贸易 A 11000 2023-11-30
8 2023-12-01 跨境贸易 A 12000 2023-12-31
9 2024-01-01 跨境贸易 A 13000 2024-01-31
10 2024-02-01 跨境贸易 A 14000 2024-02-29
11 2023-01-01 跨境贸易 B 1000 2023-01-31
12 2023-02-01 跨境贸易 B 2000 2023-02-28
13 2023-04-01 跨境贸易 B 4000 2023-04-30
14 2023-05-01 跨境贸易 B 5000 2023-05-31
15 2023-07-01 跨境贸易 B 7000 2023-07-31
16 2023-10-01 跨境贸易 B 10000 2023-10-31
17 2023-11-01 跨境贸易 B 11000 2023-11-30
18 2023-12-01 跨境贸易 B 12000 2023-12-31
19 2024-01-01 跨境贸易 B 13000 2024-01-31
20 2024-02-01 跨境贸易 B 14000 2024-02-29
df=df.set_index('最后一天')
skip_months=[6,11]
df['m1']=df[~df['匹配日期'].dt.month.isin(skip_months)].sort_values(by='匹配日期').groupby(['分类','品牌'])['销售金额'].shift(periods=1,freq='M')
df['m2']=df[~df['匹配日期'].dt.month.isin(skip_months)].sort_values(by='匹配日期').groupby(['分类','品牌'])['销售金额'].shift(periods=2,freq='M')
df['m3']=df[~df['匹配日期'].dt.month.isin(skip_months)].sort_values(by='匹配日期').groupby(['分类','品牌'])['销售金额'].shift(periods=3,freq='M')
df['m4']=df[~df['匹配日期'].dt.month.isin(skip_months)].sort_values(by='匹配日期').groupby(['分类','品牌'])['销售金额'].shift(periods=4,freq='M')
报错:cannot reindex on an axis with duplicate labels
请问这种情况要怎么处理才能实现按月偏移呢
【以下回答由 GPT 生成】
这个问题可以通过使用pd.Grouper
来解决。pd.Grouper
是Pandas库中用于将数据按一定规则进行分组的工具。
以下是优化后的代码:
import pandas as pd
# 假设数据框的列名分别为"日期"、"分类"、"品牌"、"销售金额"
# 假设日期列的类型为datetime64[ns]
# 将日期列转换为索引列,并按照日期排序
df = df.set_index("日期").sort_index()
# 设置需要偏移的月份
skip_months = [6, 11]
# 定义一个函数,用于进行偏移并计算销售金额
def shift_sales_amount(group):
group["销售金额"] = group["销售金额"].shift()
return group
# 使用pd.Grouper进行分组,按分类和品牌分组,并在每组中应用shift_sales_amount函数
df["m1"] = df.groupby([pd.Grouper(freq="M"), "分类", "品牌"]).apply(shift_sales_amount)
# 继续进行m2和m3的偏移
df["m2"] = df.groupby([pd.Grouper(freq="M"), "分类", "品牌"]).apply(shift_sales_amount)
df["m3"] = df.groupby([pd.Grouper(freq="M"), "分类", "品牌"]).apply(shift_sales_amount)
# 重置索引,将日期列恢复为普通列
df = df.reset_index()
# 打印优化后的数据框
print(df)
这段代码的优化之处在于: 1. 使用pd.Grouper
进行分组,可以直接指定偏移的频率(月份)。 2. 使用groupby
函数并应用自定义的shift_sales_amount
函数,避免了重复代码。 3. 最后,通过reset_index
函数将日期列恢复为普通列。
请注意,这段代码假设日期列的类型为datetime64[ns]
,如果你的日期列类型不同,请进行相应的更改和调整。