面对结构不一致的CSV和Excel数据,如何一步到位地完成读取、对齐与合并,并生成一份清晰展示差异值和条件标记的新表格?本文将为你揭晓答案。
在日常的数据核对与整合工作中,我们经常面临一个典型难题:需要快速合并来自不同系统、列名不统一、日期格式各异的CSV与Excel文件,并精准定位关键数值字段之间的差异。本文将以一个具体场景为例,逐步拆解这一数据处理流程。
假设您手中有两份数据源:一份是包含 test date、id、values 1 三列的CSV文件;另一份是Excel文件,其有效表头起始于第5行,包含 id、date(格式为“月/日/年”)、values 2 三列。我们的核心目标是:通过 id 关联两条记录,统一混乱的日期格式,计算 values 2 与 values 1 的差值,并自动标记出差值“是否超过2”。
以下是一套完整、可直接复用的Python解决方案,兼顾了代码的健壮性与可读性:
import pandas as pd
# 1. 分别读取 CSV 和 Excel(跳过前4行,使第5行为列名)
df_csv = pd.read_csv("test.csv")
df_excel = pd.read_excel("test.xlsx", skiprows=4)
# 2. 标准化列名,便于后续合并
df_csv = df_csv.rename(columns={"test date": "date", "values 1": "value_1"})
df_excel = df_excel.rename(columns={"values 2": "value_2"})
# 3. 统一日期格式:将 Excel 中的 date 转为 YYYY-MM-DD 字符串(与 CSV 一致)
df_excel["date"] = pd.to_datetime(df_excel["date"]).dt.strftime("%Y-%m-%d")
# 4. 基于 'id' 和 'date' 双键合并(推荐:避免仅用 id 导致多对一歧义)
merged = pd.merge(df_csv, df_excel, on=["id", "date"], how="inner")
# 5. 构建结果表,计算差异并添加布尔标记
result = merged[["date", "id", "value_1", "value_2"]].copy()
result["discrepancy"] = result["value_2"] - result["value_1"]
result["Over 2?"] = result["discrepancy"] > 2 # 自动转为布尔值,可选 .map({True: "yes", False: "no"})
print(result)
操作过程中的关键注意事项:
- 若Excel文件的表头不在第5行,只需灵活调整
skiprows参数即可;对于更复杂的表头结构,可考虑使用header=None配合iloc进行手动指定。 - 使用
["id", "date"]双键进行合并,比仅用id更稳妥,能有效防止同一ID对应多个日期时产生意外的笛卡尔积,确保数据匹配的准确性。 pd.to_datetime(...).dt.strftime()这一组合操作,确保了不同来源日期格式的完全对齐,避免了因字符串格式差异导致的匹配失败问题。- 生成的
"Over 2?"列默认为布尔型(True/False)。若需要更直观的“是”/“否”或“yes”/“no”显示,可在最后追加一行代码进行映射转换:result["Over 2?"] = result["Over 2?"].map({True: "yes", False: "no"}) - 最终的结果数据框,可以轻松导出为新的Excel文件,方便分享与存档:
result.to_excel("discrepancy_report.xlsx", index=False)。
这套流程清晰直接,既适合数据分析的初学者快速上手,也能高效满足日常数据稽核、自动化报表生成及数据清洗的需求。下次再遇到结构混乱的源数据时,不妨尝试运用这个方法,实现高效的数据对齐与差异分析。
