基于双DataFrame生成多品类交易净额未售商品时间序列折线图
解决方案步骤
1. 数据预处理
- 统一日期列格式为
datetime类型,避免日期格式不匹配问题 - 补全Df2中缺失的日期记录(按品类分组补全,缺失日期销量填0)
- 确保两个DataFrame都包含商品品类标识列(假设列名为
Category,若原数据无此列需先确认数据结构)
import pandas as pd import matplotlib.pyplot as plt # 转换日期格式 Df1['Transaction_DATE'] = pd.to_datetime(Df1['Transaction_DATE']) Df1['Termination_DATE'] = pd.to_datetime(Df1['Termination_DATE']) Df2['Date'] = pd.to_datetime(Df2['Date']) # 假设Df2日期列名为Date # 生成全局日期范围(从Df1最早交易日到最晚终止日) full_date_range = pd.date_range(start=Df1['Transaction_DATE'].min(), end=Df1['Termination_DATE'].max()) # 按品类补全Df2的日期序列,缺失日期销量设为0 Df2_full = Df2.groupby('Category').apply( lambda x: x.set_index('Date').reindex(full_date_range).fillna(0).reset_index() ).rename(columns={'index': 'Date'}).droplevel(0)
2. 展开可售新增量时间序列
- 按品类将Df1的
TRANSACTION(可售新增量)映射到对应日期,非交易日期新增量设为0 - 仅保留各品类终止销售日期之前的数据
def expand_transaction_group(df): category = df['Category'].iloc[0] start_date = df['Transaction_DATE'].min() end_date = df['Termination_DATE'].max() # 生成该品类的有效日期范围 category_date_range = pd.date_range(start=start_date, end=end_date) # 匹配交易日期的新增量 trans_expanded = pd.DataFrame({'Date': category_date_range, 'Category': category}) trans_expanded = trans_expanded.merge( df[['Transaction_DATE', 'TRANSACTION', 'Category']], left_on=['Date', 'Category'], right_on=['Transaction_DATE', 'Category'], how='left' ).fillna(0) trans_expanded['Daily_Add'] = trans_expanded['TRANSACTION'] return trans_expanded[['Date', 'Category', 'Daily_Add']] # 按品类展开新增量数据 Df1_expanded = Df1.groupby('Category').apply(expand_transaction_group).droplevel(0)
3. 计算未售商品净额时间序列
- 合并新增量与销量数据,按品类计算累计新增量、累计销量
- 未售净额 = 累计新增量 - 累计销量
# 合并新增量和补全后的销量数据 merged_data = pd.merge(Df1_expanded, Df2_full, on=['Date', 'Category'], how='left').fillna(0) # 计算累计值与未售净额 merged_data['Cumulative_Add'] = merged_data.groupby('Category')['Daily_Add'].cumsum() merged_data['Cumulative_Sales'] = merged_data.groupby('Category')['Proceeds'].cumsum() merged_data['Unsold_Net'] = merged_data['Cumulative_Add'] - merged_data['Cumulative_Sales'] # 过滤掉各品类终止日期之后的数据 merged_data = merged_data[ merged_data['Date'] <= merged_data.groupby('Category')['Termination_DATE'].transform('max') ]
4. 绘制品类未售净额折线图
- 按品类分组绘制折线图,直观展示各品类未售净额的时间趋势
plt.figure(figsize=(12, 6)) # 遍历每个品类绘制折线 for category, group in merged_data.groupby('Category'): plt.plot(group['Date'], group['Unsold_Net'], linewidth=2, label=category) # 图表样式设置 plt.title('各品类未售商品净额时间趋势') plt.xlabel('日期') plt.ylabel('未售净额') plt.legend(loc='upper right') plt.grid(alpha=0.3) plt.xticks(rotation=45) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者alec22
相关产品推荐
相关产品推荐

