Python*应用 | 定期更新数据表

背景

我们的 Little Jing 又登场了。

这次他接到了新的任务。公司有两个重要的Excel表格:一个是主数据表格,记录了所有产品的销售情况;另一个是每日销售报告,每天都会更新新的销售数据。

任务是每天将这些新数据整合到主数据表格中,并进行分类汇总,以便于管理层可以快速获取关键的销售信息和趋势。

文件内容长这样: 

图片[1]-Python*应用 | 定期更新数据表-不念博客
图片[2]-Python*应用 | 定期更新数据表-不念博客

实现思路

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文件。

最后的数据表现

图片[3]-Python*应用 | 定期更新数据表-不念博客

编程思维

面向场景,我们来看下今天的编程思维是什么。

灵活性与鲁棒性

在设计数据处理脚本时,考虑到数据源可能会发生变化(如新的列被添加,或格式稍有变动)。编写代码时应考虑这些可能性,比如通过动态识别列名而不是硬编码。

这样的设计使程序更加灵活和鲁棒,能够适应未来数据格式的变化,减少因数据变动带来的维护工作。

预防性错误处理

预见并处理可能出现的错误,例如文件不存在、格式不正确或数据损坏的情况。在脚本中实现适当的异常处理机制。

增强代码的稳定性和可靠性,提高用户体验,避免因意外情况导致的数据丢失或程序崩溃。

自动化与效率优化

通过自动化日常任务(如数据整合和报告生成)来提高效率。考虑使用任务调度来定时执行脚本。

自动化减少了重复劳动,使数据分析师可以专注于更复杂的分析工作,提高整体工作效率。

可扩展性考虑

设计时考虑未来可能的需求变化,比如增加新的数据源或改变报告格式。

使得将来的扩展或修改更加容易,不需要重写整个系统。

清晰的代码文档与注释

编写清晰的文档和注释,尤其是对于复杂的数据处理逻辑。

使得他人(包括未来的自己)能够更容易理解和维护代码,促进团队协作。

将这些编程思维应用于数据管理场景,不仅能提高当前任务的效率和准确性,还能确保系统的长期可维护性和可扩展性。

© 版权声明
THE END