当前位置: 首页 > news >正文

通过门店销售明细表用Python Pandas得到每月每个门店的销冠和按月的同比环比数据

假设我在本地有Excel销售表,包含ID主键、门店ID、日期、销售员姓名和销售额,需要用Pandas统计出每个月所有门店和各门店销售额最高的人,不一定是一个人,以及他所在的门店ID和月总销售额。

步骤1:导入数据并处理日期

import pandas as pd# 读取Excel文件
df = pd.read_excel('sales.xlsx')# 转换日期格式并提取月份
df['日期'] = pd.to_datetime(df['日期'])
df['月份'] = df['日期'].dt.to_period('M')  # 或使用.strftime('%Y-%m')

步骤2:统计各门店每月销售额最高的销售员

# 按月份、门店、销售员分组求和
store_monthly_sales = df.groupby(['月份', '门店ID', '销售员姓名'])['销售额'].sum().reset_index()# 找出每个门店每月的最高销售额
store_monthly_sales['max_sales'] = store_monthly_sales.groupby(['月份', '门店ID'])['销售额'].transform('max')
highest_per_store = store_monthly_sales[store_monthly_sales['销售额'] == store_monthly_sales['max_sales']].drop(columns='max_sales')

步骤3:统计所有门店每月销售额最高的销售员

# 按月份和销售员分组求和,并合并门店ID
all_store_sales = df.groupby(['月份', '销售员姓名']).agg(总销售额=('销售额', 'sum'),门店ID=('门店ID', lambda x: ', '.join(map(str, x.unique())))
).reset_index()# 找出每月最高总销售额
all_store_sales['max_total'] = all_store_sales.groupby('月份')['总销售额'].transform('max')
highest_all_stores = all_store_sales[all_store_sales['总销售额'] == all_store_sales['max_total']].drop(columns='max_total')

步骤4:导出结果到Excel

with pd.ExcelWriter('result.xlsx') as writer:highest_per_store.to_excel(writer, sheet_name='各门店月度冠军', index=False)highest_all_stores.to_excel(writer, sheet_name='全公司月度冠军', index=False)

结果说明

  • 各门店月度冠军:包含月份、门店ID、销售员姓名及其销售额,可能有多个销售员并列。
  • 全公司月度冠军:包含月份、销售员姓名、总销售额及其涉及的所有门店ID,可能有多个销售员并列。

假设我在本地有Excel销售表,包含ID主键、门店ID、日期、销售员姓名和销售额,需要用Pandas统计出按月统计的同比和环比数据,当前月如果不是月底的话,同比或环比数据需要取得上个月或者去年1日到对应的日期的总销售额值。

import pandas as pdfrom pandas.tseries.offsets import DateOffsetdef calculate_yoy_mom_sales(file_path, current_date=None):# 读取数据并处理日期df = pd.read_excel(file_path)df['日期'] = pd.to_datetime(df['日期'])# 设置当前日期(默认为数据最新日期)current_date = pd.to_datetime(current_date) if current_date else df['日期'].max()# 生成日期范围辅助列df['年月'] = df['日期'].dt.to_period('M')# 计算所有可能的月份范围min_date = df['日期'].min()max_date = current_datefull_months = pd.period_range(start=min_date, end=max_date, freq='M')results = []for period in full_months:# 当前统计月份信息month_start = period.start_timemonth_end = min(period.end_time, current_date)# 当前时间段销售额current_mask = (df['日期'] >= month_start) & (df['日期'] <= month_end)current_sales = df[current_mask]['销售额'].sum()# 同比计算(去年同时间段)last_year_start = month_start - DateOffset(years=1)last_year_end = month_end - DateOffset(years=1)last_year_mask = (df['日期'] >= last_year_start) & (df['日期'] <= last_year_end)yoy_sales = df[last_year_mask]['销售额'].sum()# 环比计算(上月同时间段)last_month_start = month_start - DateOffset(months=1)last_month_end = month_end - DateOffset(months=1)# 确保环比结束日期不超过上月最后一天last_month_end = min(last_month_end, last_month_start + pd.offsets.MonthEnd(1))mom_mask = (df['日期'] >= last_month_start) & (df['日期'] <= last_month_end)mom_sales = df[mom_mask]['销售额'].sum()results.append({'统计月份': period.strftime('%Y-%m'),'开始日期': month_start.date(),'结束日期': month_end.date(),'当月销售额': current_sales,'同比销售额': yoy_sales,'环比销售额': mom_sales,'同比增幅': (current_sales - yoy_sales) / yoy_sales if yoy_sales != 0 else None,'环比增幅': (current_sales - mom_sales) / mom_sales if mom_sales != 0 else None})result_df = pd.DataFrame(results)return result_df# 使用示例
result = calculate_yoy_mom_sales('sales.xlsx', '2023-06-15')
print(result)

方案特点:

  1. 动态日期处理

    • 自动处理非完整月份(如当前月到15号)
    • 智能对齐同比/环比时间段(自动调整到相同天数)
    • 处理月份天数差异(如2月28日对比)
  2. 输出结果包含

    • 统计月份
    • 实际统计日期范围
    • 当月销售额
    • 同比销售额(去年同期相同天数)
    • 环比销售额(上月同期相同天数)
    • 同比/环比增长率
  3. 使用方式

    # 自动使用数据最新日期
    result = calculate_yoy_mom_sales('sales.xlsx') # 指定截止日期
    result = calculate_yoy_mom_sales('sales.xlsx', '2023-06-15')
    
  4. 处理边界情况

    • 当月天数 > 比较月份天数时自动截断到月末
    • 处理零销售额时的增长率计算
    • 自动生成完整的时间序列(包含无销售的月份)

输出示例:

统计月份开始日期结束日期当月销售额同比销售额环比销售额同比增幅环比增幅
2023-062023-06-012023-06-151500001200001400000.250.071
2023-052023-05-012023-05-313000002800002500000.0710.2

注意事项:

  1. 保证日期字段的完整性,缺失日期会导致统计偏差
  2. 无历史数据时增长率显示为None
  3. 建议配合数据验证使用(如检查日期范围是否合理)
  4. 结果包含所有自然月,即使当月没有销售数据
http://www.xdnf.cn/news/153343.html

相关文章:

  • 搜广推校招面经八十二
  • Springboot集成SSE实现消息推送+RabbitMQ解决集群环境下SSE通道跨节点事件推送问题
  • 计算机网络 | Chapter1 计算机网络和因特网
  • CANape与MATLAB数据接口技术详解
  • Java进阶--面向对象设计原则
  • 基于html-css-js的尚有选页面源码详细
  • 如何解决IDE项目启动报错 error:0308010C:digital envelope routines::unsupported 问题
  • 图论---LCA(倍增法)
  • 从新手到高手:小程序开发进阶技巧分享
  • SQL 查询进阶:WHERE 子句与连接查询详解
  • Myweb项目——面试题总结
  • 多模态大语言模型arxiv论文略读(四十二)
  • ZYNQ笔记(十四):基于 BRAM 的 PS、PL 数据交互
  • Pygame字体与UI:打造游戏菜单和HUD界面
  • 【含文档+PPT+源码】基于Django的新闻推荐系统的设计与实现
  • 第八部分:缓解 RAG 中的幻觉
  • 认识哈希以及哈希表的模拟实现
  • 嵌入式硬件开发工具---万用表---示波器---仿真器
  • 解构与重构:“整体部分”视角下的软件开发思维范式
  • Dify框架面试内容整理-Dify框架
  • 学习设计模式《六》——抽象工厂方法模式
  • 大数据模型现状分析
  • 4.25test
  • 2025蓝桥省赛c++B组第二场题解
  • 在WSL2+Ubuntu22.04中通过conda pack导出一个conda环境包,然后尝试导入该环境包
  • WPF与C++ 动态库交互
  • 职业教育新形态数字教材的建设与应用:重构教育生态的数字化革命
  • 文件操作及读写-爪哇版
  • 一些常见的资源池管理、分布式管理和负载均衡的监控工具
  • c++ package_task