背景
我们的 Little Jing 又登场了。
这次他接到了新的任务。公司有两个重要的Excel表格:一个是主数据表格,记录了所有产品的销售情况;另一个是每日销售报告,每天都会更新新的销售数据。
任务是每天将这些新数据整合到主数据表格中,并进行分类汇总,以便于管理层可以快速获取关键的销售信息和趋势。
文件内容长这样:
实现思路
Little Jing 在写代码实现之前想了想,这个要怎么做呢?
自动读取数据
首先,需要建立一个机制来自动读取每日销售报告和主数据表。这可以通过编写Python脚本来实现,该脚本将定期运行,自动读取存储在指定位置的Excel文件。(这里我们今天先不做哦~记下了记下了~)
数据整合
读取数据后,接下来的步骤是将每日销售数据合并到主数据表中。这一步骤涉及到数据对齐,确保数据的日期、产品ID等关键字段匹配。
数据清洗
在合并数据之前,可能需要进行数据清洗。这包括识别并处理缺失值、错误数据和重复记录等,确保数据的质量。
数据汇总和分类
合并和清洗数据之后,下一步是对数据进行分类汇总。根据管理层的需求,可以按产品、时间或其他关键指标对数据进行分组,并计算总销量、平均销售额等统计数据。
生成报告
最后一步是基于整理好的数据生成报告。报告可能包括关键指标的总结、趋势图表等,以便管理层快速获取所需信息。
自动化和定时执行
将以上步骤集成到一个Python脚本中,并利用任务调度工具(如Windows的Task Scheduler或Linux的Cron)来实现脚本的定时自动执行。(这里我们今天也不做哦~记下了记下了~)
开始写代码
思路理完,那就开始写吧~
先来看下文件的架构
project
│
├── py文件
│
├── daily
│ ├── sales_23.xlsx
│ ├── sales_24.xlsx
│ └── sales_25.xlsx
│
└── main.xlsx
这里我们放置了三个 sales 报告文件作为示例,同时把文件的层架做了区分,方便我们获取文件。
实际工作中,文件和文件夹都是要作为参数传入的哦~~
具体的代码如下
import pandas as pd
from datetime import datetime
# 定义文件路径
main_data_path = 'main_data.xlsx' # 主数据表路径
daily_data_folder = 'daily_reports/' # 每日报告文件夹路径
# 当天日期
today = datetime.now().strftime('%Y-%m-%d')
# 尝试读取当天的销售报告,如果文件不存在则打印错误信息
try:
daily_data_path = f'{daily_data_folder}sales_report_{today}.xlsx'
daily_data = pd.read_excel(daily_data_path)
except FileNotFoundError:
print(f"今日销售报告({daily_data_path})未找到。")
exit()
# 读取主数据表
# 读取文件时使用通用数据类型
main_data = pd.read_excel(main_data_path, dtype=object)
# 确保主数据表中的'date'列是datetime类型
if main_data['date'].dtype != 'datetime64[ns]':
main_data['date'] = pd.to_datetime(main_data['date'])
# 数据清洗(确保销售数量是正数)
daily_data = daily_data[daily_data['sales_quantity'] > 0]
# 确保日报数据中的'date'列是datetime类型
if daily_data['date'].dtype != 'datetime64[ns]':
daily_data['date'] = pd.to_datetime(daily_data['date'])
# 数据合并
combined_data = pd.concat([main_data, daily_data], ignore_index=True)
# 数据分类与汇总
# 例如,按产品ID和日期汇总销售数量
summary = combined_data.groupby(['product_id', 'date'])['sales_quantity'].sum().reset_index()
# 保存更新后的主数据表
combined_data.to_excel(main_data_path, index=False)
# 保存分类汇总数据
summary.to_excel(f'summary_{today}.xlsx', index=False)
print(f"数据处理完成,已更新主数据表并生成今日汇总报告:summary_{today}.xlsx")
代码详细解释
我们来看看这段代码都干了啥~
导入Pandas库
import pandas as pd
这一行导入了Pandas库,它是Python中处理数据的主要工具之一,特别擅长于处理和分析表格数据。
获取当前日期
from datetime import datetime
today = datetime.now().strftime('%Y-%m-%d')
这里我们使用了datetime
库来获取当前日期,并格式化为年-月-日
的形式。这将用于识别今天的销售报告。
定义文件路径
main_data_path = 'main_data.xlsx'
daily_data_folder = 'daily_reports/'
这两行定义了主数据表和每日报告的存储路径。
读取每日销售报告
try:
daily_data_path = f'{daily_data_folder}sales_report_{today}.xlsx'
daily_data = pd.read_excel(daily_data_path)
except FileNotFoundError:
print(f"今日销售报告({daily_data_path})未找到。")
exit()
这段代码尝试读取当天的销售报告文件。如果文件不存在,它会打印一条错误信息并停止执行。
读取主数据表
main_data = pd.read_excel(main_data_path, dtype=object)
这行代码读取主数据表格。读取 Excel 文件时使用通用的数据类型,如 object,这将避免在读取时进行类型推断。
确保’date’列是datetime类型
if daily_data['date'].dtype != 'datetime64[ns]':
daily_data['date'] = pd.to_datetime(daily_data['date'])
这段代码是用来确保在 daily_data DataFrame 中的 ‘date’ 列是 datetime 类型的。
这个过程对于处理日期和时间数据非常重要,因为它确保了日期数据在之后的操作中能被正确处理。
数据清洗
daily_data = daily_data[daily_data['sales_quantity'] > 0]
这里我们假设需要确保销售数量是正数。这行代码移除了销售数量不是正数的行。
数据合并
combined_data = pd.concat([main_data, daily_data], ignore_index=True)
使用pd.concat
方法将主数据和每日数据合并在一起。ignore_index=True
参数确保合并后的数据集有一个连续的索引。
数据分类与汇总
summary = combined_data.groupby(['product_id', 'date'])['sales_quantity'].sum().reset_index()
这行代码按产品ID和日期对销售数量进行分组汇总。
保存更新后的数据
combined_data.to_excel(main_data_path, index=False)
summary.to_excel(f'summary_{today}.xlsx', index=False)
这两行代码将更新后的主数据和汇总数据分别保存为Excel文件。
最后的数据表现
编程思维
面向场景,我们来看下今天的编程思维是什么。
灵活性与鲁棒性
在设计数据处理脚本时,考虑到数据源可能会发生变化(如新的列被添加,或格式稍有变动)。编写代码时应考虑这些可能性,比如通过动态识别列名而不是硬编码。
这样的设计使程序更加灵活和鲁棒,能够适应未来数据格式的变化,减少因数据变动带来的维护工作。
预防性错误处理
预见并处理可能出现的错误,例如文件不存在、格式不正确或数据损坏的情况。在脚本中实现适当的异常处理机制。
增强代码的稳定性和可靠性,提高用户体验,避免因意外情况导致的数据丢失或程序崩溃。
自动化与效率优化
通过自动化日常任务(如数据整合和报告生成)来提高效率。考虑使用任务调度来定时执行脚本。
自动化减少了重复劳动,使数据分析师可以专注于更复杂的分析工作,提高整体工作效率。
可扩展性考虑
设计时考虑未来可能的需求变化,比如增加新的数据源或改变报告格式。
使得将来的扩展或修改更加容易,不需要重写整个系统。
清晰的代码文档与注释
编写清晰的文档和注释,尤其是对于复杂的数据处理逻辑。
使得他人(包括未来的自己)能够更容易理解和维护代码,促进团队协作。
将这些编程思维应用于数据管理场景,不仅能提高当前任务的效率和准确性,还能确保系统的长期可维护性和可扩展性。