如何在指定日期区间内将月度销售数据追加至补货订单DataFrame?
解决方案:将指定区间内的月度平均销量追加到补货订单DataFrame
现有两个DataFrame:
grouper:按国家、产品、月份分组计算出的月度平均销量(当前为多级索引结构)products:补货订单数据,包含产品、日期、补货数量
需求是把products首尾日期区间内的所有月度平均销量(以负数值形式)追加到products中。
原代码存在的问题
grouper是groupby后的多级索引对象,无法直接用grouper['Product']方式索引,需先将多级索引转为普通列pd.DataFrame.append()已被弃用,且循环追加效率极低- 循环内的索引匹配逻辑有误,未正确关联产品与对应月份的销量
最优实现步骤
步骤1:转换grouper的结构
将多级索引转为普通列,方便后续数据匹配:
# 把groupby后的多级索引转为列,同时重命名销量列 grouper_df = grouper.reset_index().rename(columns={'Sales Quantity [QTY]': 'Avg_Sales'})
步骤2:生成目标日期区间的月度序列
先确保日期列格式正确,再提取首尾日期生成月度起始日期序列:
# 确保Date列是datetime类型 products['Date'] = pd.to_datetime(products['Date']) # 获取日期区间首尾 start_date = products['Date'].min() end_date = products['Date'].max() # 生成月度起始日期序列 date_range = pd.date_range(start=start_date, end=end_date, freq='MS')
步骤3:生成销售记录数据
为每个日期匹配对应产品的月度平均销量,生成负数值的销售记录:
# 创建包含日期和对应月份的临时DataFrame date_df = pd.DataFrame({'Date': date_range, 'Month': date_range.month}) # 获取目标产品(单产品场景) target_product = products['Product'].iloc[0] # 筛选当前产品的平均销量数据 product_avg_sales = grouper_df[grouper_df['Product'] == target_product] # 合并日期与平均销量数据 sales_records = pd.merge(date_df, product_avg_sales, on='Month', how='left') # 整理成目标格式:保留Product、Date,Quantity为负的平均销量(保留两位小数) sales_records = sales_records[['Product', 'Date', 'Avg_Sales']].rename(columns={'Avg_Sales': 'Quantity'}) sales_records['Quantity'] = -sales_records['Quantity'].round(2)
步骤4:合并原补货订单和销售记录
将生成的销售记录追加到原products中:
# 合并两个DataFrame final_df = pd.concat([products, sales_records], ignore_index=True) # 查看结果 print(final_df)
多产品场景扩展
如果products包含多个产品,只需在外层添加按Product分组的逻辑:
final_dfs = [] for product, group in products.groupby('Product'): # 针对当前产品生成日期区间 start_date = group['Date'].min() end_date = group['Date'].max() date_range = pd.date_range(start=start_date, end=end_date, freq='MS') date_df = pd.DataFrame({'Date': date_range, 'Month': date_range.month}) # 匹配当前产品的平均销量 product_avg_sales = grouper_df[grouper_df['Product'] == product] sales_records = pd.merge(date_df, product_avg_sales, on='Month', how='left') # 整理格式 sales_records = sales_records[['Product', 'Date', 'Avg_Sales']].rename(columns={'Avg_Sales': 'Quantity'}) sales_records['Quantity'] = -sales_records['Quantity'].round(2) # 合并当前产品的补货订单与销售记录 final_dfs.append(pd.concat([group, sales_records], ignore_index=True)) # 合并所有产品的结果 final_df = pd.concat(final_dfs, ignore_index=True)
内容的提问来源于stack exchange,提问作者asuidncsdk
相关产品推荐
相关产品推荐

