前言
在数据处理与分析的实际场景中,我们经常需要整合不同格式的数据,例如 Excel 表格、JSON 配置文件、HTML 报表等。本文以一个具体任务(蓝桥杯模拟练习题)为例,详细讲解如何使用 Python 的 Pandas 库结合其他工具,将三种不同格式的数据文件合并为统一的结构化输出,满足业务分析的需求。
题目地址:
本文主要解释大佬的题解
一、任务背景与目标
1.任务描述
我们需要合并三个文件的数据:
- 2022_january.xlsx(Excel 表格):存储 1 月的消费数据
- 2022_february.json(JSON 文件):存储 2 月的消费数据
- 2022_may.html(HTML 文件):存储 5 月的消费数据
2.目标输出
最终数据需整合成一个字典,结构如下:
{
"january": {
"1-1": {"food": 123, "clothes": 456, ...}, # 1月1日消费数据
"1-2": {...}
},
"february": { ... },
"may": { ... }
}
每个月份的每一天数据需包含固定的 6 个消费类别(food, clothes, vehicle, sports, loans, other),缺失类别默认值为 0。
二、数据处理全流程解析
一、任务核心目标
将 Excel 、JSON 、HTML 三种格式的数据文件,按月份 - 日期 - 消费类别的层级结构合并为统一的字典,具体要求:
- 键名规范 :月份用英文(
january
/february
/may
),日期格式为M-d
(如1-5
)。 - 消费类别 :固定 6 个类别(
food
,clothes
,vehicle
,sports
,loans
,other
),缺失值默认 0。
二、分格式数据处理步骤
1. Excel 文件(2022_january.xlsx)处理
核心问题 :从表格中提取日期和消费数据,转换为指定格式。
关键步骤:
# 1. 读取文件并跳过无效行,指定索引列
data_1_xlsx = pd.read_excel('/home/project/2022_january.xlsx', skiprows=4, index_col=2)
# 2. 删除无关列(前两列可能为序号或说明,非数据列)
data_1_xlsx = data_1_xlsx.drop(data_1_xlsx.columns[[0, 1]], axis=1)
# 3. 日期格式处理:转换为 datetime 后格式化为 M-d(如 1-5,去掉前导零)
data_1_xlsx.index = pd.to_datetime(data_1_xlsx.index).strftime('%-m-%-d')
# 4. 转换为字典:{日期: {类别: 金额}}
data_1 = {'january': data_1_xlsx.to_dict('index')}
技术点
skiprows=4
:跳过前 4 行无用数据(如标题、说明行),确保从有效数据行开始读取。index_col=2
:将第 3 列(索引 2)作为日期列(假设该列存储日期信息)。strftime('%-m-%-d')
:生成无 lead-zero 的日期(如1-1
而非01-01
),严格匹配题目要求。
2. JSON 文件(2022_february.json)处理
核心问题 :直接加载 JSON 数据,确保格式符合要求。
关键步骤:
with open('/home/project/2022_february.json', 'r') as jsonf:
data_2 = json.load(jsonf)
技术点:
- JSON 文件结构假设为
{日期: {类别: 金额}}
,与目标格式一致,可直接加载。 - 若原始数据缺失类别(题目未提及),需补全;但根据正确代码,此处直接使用原始数据(可能已满足要求)。
3. HTML 文件(2022_may.html)处理
核心问题 :解析 HTML 表格,提取日期和消费数据。
关键步骤:
# 1. 解析HTML并提取所有表头文本
with open('/home/project/2022_may.html', 'r') as htmlf:
data_5_html = htmlf.read()
data_5_html = BeautifulSoup(data_5_html, 'lxml') # 使用高效解析器
headers = [body.text for body in data_5_html.find_all('th')] # 提取所有表头
# 2. 按7个字段一组处理数据(1个日期+6个消费类别)
data_5 = {"may": {}}
for i in range(7, len(headers), 7): # 从第7个元素开始(跳过表头说明)
date = headers[i] # 日期字段(第i个元素)
values = headers[i:i+7] # 7个字段:日期+6个类别(实际用后6个)
day_data = {headers[j]: int(values[j]) for j in range(i+1, i+7)} # 提取后6个类别
data_5['may'][date] = day_data
技术点:
- 表格结构分析:假设 HTML 表格的表头和数据行按固定格式排列,每个日期对应 7 个字段(日期 + 6 个类别)。
- 索引计算 :通过
range(7, len(headers), 7)
分组,每组第一个元素为日期,后续 6 个为消费金额。 - 类型转换 :金额转换为整数(
int(values[j])
),与题目示例输出一致。
三、数据合并与格式校验
1. 合并三部分数据
data = {**data_1, **data_2, **data_5}
原理 :使用字典解包(**
)将三个月份的数据合并,键名(january
/february
/may
)自动拼接,避免重复。
2. 格式校验关键点
- 日期格式 :所有日期键必须为
M-d
形式(如1-1
),通过strftime
或直接提取确保一致性。 - 消费类别 :确保每个日期的字典包含全部 6 个类别(题目示例中
other
默认 0,但原始数据可能已包含,无需额外补全)。 - 绝对路径 :使用题目规定的绝对路径(如
/home/project/...
),避免文件读取错误。
四、完整代码逻辑总结
- Excel 处理: 跳过无效行,选择正确索引列,格式化日期,转换为字典。
- JSON 处理:直接加载,假设数据结构已符合要求(键为日期,值为类别金额)。
- HTML 处理:解析表格,按固定字段分组提取日期和消费数据,转换为整数。
- 合并:通过字典解包合并三部分数据,确保键名和格式完全符合目标结构。
五、易错点与解决方案
- 文件路径错误 :必须使用绝对路径(题目明确要求),避免因工作目录变化导致的
FileNotFoundError
。 - 日期格式不匹配 :使用
pd.to_datetime
和strftime
严格控制日期格式,确保无前导零(如%-m
)。 - 表格结构解析错误 :通过打印
headers
或数据行调试,确认 HTML 表格的字段顺序和分组逻辑(如每组 7 个字段)。 - 数据类型不一致 :消费金额统一为整数(与示例一致),使用
int()
转换,避免浮点型误差。
六、总结
本题核心是多格式数据的解析与结构化转换 ,需针对每种格式的特点选择合适的库(pandas
处理表格,json
处理键值对,BeautifulSoup
处理 HTML 表格),并严格按照题目要求的层级结构组织数据。关键在于格式细节的精确匹配(日期、类别名称、数据类型),以及通过调试确保每一步解析后的数据结构符合预期。