如何简化按日期筛选数据并计算区域销售增长率的代码?
区域销售增长率计算:代码简化方案
数据集
Customer_ID| Region| Sales_Date| Sales_Amount 183984 | 1 | 01-04-23 | 1232.44 183991 | 2 | 01-04-23 | 23.41 128943 | 1 | 01-04-23 | 7562.22
分析目标
对比最近4周与之前4周的销售数据,计算各区域的销售增长率。
当前代码问题与简化方案
先提下你当前代码里的几个明显问题:
- 日期筛选逻辑写反了:
current_4_wks_start是基准日,current_4_wks_end是往前推4周,筛选时应该是Sales_Date >= 结束日且<= 开始日 - 前4周的筛选完全复用了当前4周的日期条件,等于没区分两个区间
- 增长率公式没写完,缺少右括号
下面是简化后的实现,核心思路是一次标记区间+批量聚合,避免重复操作:
from datetime import datetime, timedelta import pandas as pd # 1. 定义时间区间(先把日期逻辑理清楚) current_date = datetime(2023, 4, 8) # 最近4周:从基准日往前推4周到基准日 current_4w_start = current_date - timedelta(weeks=4) current_4w_end = current_date # 之前4周:和最近4周间隔1周,再往前取4周 past_4w_start = current_4w_start - timedelta(weeks=5) # 间隔1周 + 4周时长 past_4w_end = current_4w_start - timedelta(weeks=1) # 2. 给每条销售数据标记所属时间区间 def mark_period(sale_date): if current_4w_start <= sale_date <= current_4w_end: return 'current_4w' elif past_4w_start <= sale_date <= past_4w_end: return 'past_4w' else: return None # 先确保Sales_Date是datetime类型(如果还没转的话) df_sales_ytd['Sales_Date'] = pd.to_datetime(df_sales_ytd['Sales_Date'], format='%d-%m-%y') df_sales_ytd['period'] = df_sales_ytd['Sales_Date'].apply(mark_period) # 只保留需要的两个区间数据 df_target = df_sales_ytd[df_sales_ytd['period'].notna()] # 3. 按区域+区间聚合,直接转成宽表(省去merge步骤) df_agg = df_target.groupby(['Region', 'period'])['Sales_Amount'].sum().unstack(fill_value=0) # 重命名列更直观 df_agg = df_agg.rename(columns={'current_4w': 'current_4_nrx', 'past_4w': 'previous_4_nrx'}) # 4. 计算增长率,处理分母为0的情况(避免报错) df_agg['growth_4'] = df_agg.apply( lambda row: (row['current_4_nrx'] - row['previous_4_nrx']) / row['previous_4_nrx'] if row['previous_4_nrx'] != 0 else None, axis=1 ) # 转成最终的结构化DataFrame df_4_growth = df_agg.reset_index()
简化优势
- 只做一次数据筛选和分组,减少代码冗余
- 用
unstack直接将分组结果转成宽表,省去手动合并两个数据集的步骤 - 增加了日期类型转换和分母为0的异常处理,代码更健壮
- 时间区间的定义更清晰,逻辑不易出错
内容的提问来源于stack exchange,提问作者dsexplorer
相关产品推荐
相关产品推荐

