Python Pandas合并多个Excel表格实战指南


Pandas是Python数据分析的核心库,提供了强大的Excel表格处理能力。本文将详细介绍如何使用Pandas高效合并多个Excel文件,涵盖各种常见场景和进阶技巧。

一、基础合并方法

1. 合并相同结构的Excel文件

当多个Excel文件具有完全相同的列结构时,可以使用简单的纵向合并:

import pandas as pd
import glob

# 获取所有Excel文件
all_files = glob.glob("data/*.xlsx")  # 支持.xls和.xlsx

# 读取并合并
df_list = []
for file in all_files:
    df = pd.read_excel(file)
    df_list.append(df)

combined_df = pd.concat(df_list, ignore_index=True)

# 保存合并结果
combined_df.to_excel("combined_data.xlsx", index=False)

2. 处理不同Sheet的合并

当数据分散在不同Sheet但结构相同时:

# 读取单个文件中的多个Sheet
file_path = "multi_sheet_data.xlsx"
sheets_dict = pd.read_excel(file_path, sheet_name=None)

# 合并所有Sheet
all_sheets = []
for sheet_name, df in sheets_dict.items():
    df['source_sheet'] = sheet_name  # 添加来源标记
    all_sheets.append(df)

combined_sheets = pd.concat(all_sheets, ignore_index=True)

二、处理结构差异的表格

1. 列名不完全相同的情况

# 方法1:只保留共有列
common_columns = set()
for file in all_files:
    df = pd.read_excel(file, nrows=0)  # 只读取列名
    common_columns.update(df.columns)

combined_df = pd.concat(
    [pd.read_excel(file)[list(common_columns)] for file in all_files],
    ignore_index=True
)

# 方法2:保留所有列,缺失值填充NA
combined_df = pd.concat(
    [pd.read_excel(file) for file in all_files],
    ignore_index=True,
    sort=False  # 避免列排序
)

2. 添加来源标识列

combined_data = pd.DataFrame()
for i, file in enumerate(all_files):
    df = pd.read_excel(file)
    df['source_file'] = file  # 添加来源文件列
    df['file_index'] = i     # 添加文件序号
    combined_data = pd.concat([combined_data, df], ignore_index=True)

三、高级合并技巧

1. 基于关键列的横向合并(类似SQL JOIN)

# 假设有两个需要关联的表格
df1 = pd.read_excel("orders.xlsx")
df2 = pd.read_excel("customers.xlsx")

# 内连接合并
merged_df = pd.merge(
    df1, 
    df2, 
    on="customer_id",  # 关联键
    how="inner"       # 连接方式:inner/left/right/outer
)

2. 大数据量分块处理

当处理大型Excel文件时,使用分块读取避免内存不足:

chunk_size = 10000  # 每次处理1万行
chunks = []

for file in all_files:
    for chunk in pd.read_excel(file, chunksize=chunk_size):
        chunks.append(chunk)

# 合并分块
combined_df = pd.concat(chunks, ignore_index=True)

3. 自定义合并逻辑

def custom_merge(df1, df2):
    """自定义合并逻辑示例"""
    # 只合并df2中存在但df1中没有的客户
    new_customers = df2[~df2['customer_id'].isin(df1['customer_id'])]
    return pd.concat([df1, new_customers], ignore_index=True)

df1 = pd.read_excel("existing_customers.xlsx")
df2 = pd.read_excel("new_customers.xlsx")
result_df = custom_merge(df1, df2)

四、性能优化方案

1. 使用更高效的数据格式

# 先将Excel转为Parquet等高效格式
for file in all_files:
    df = pd.read_excel(file)
    df.to_parquet(file.replace(".xlsx", ".parquet"))

# 然后合并Parquet文件
parquet_files = glob.glob("data/*.parquet")
dfs = [pd.read_parquet(f) for f in parquet_files]
combined_df = pd.concat(dfs, ignore_index=True)

2. 多进程加速合并

from multiprocessing import Pool

def read_excel(file):
    return pd.read_excel(file)

with Pool(processes=4) as pool:  # 使用4个进程
    df_list = pool.map(read_excel, all_files)

combined_df = pd.concat(df_list, ignore_index=True)

3. 内存优化技巧

# 指定数据类型减少内存占用
dtype_dict = {
    'id': 'int32',
    'price': 'float32',
    'description': 'category'
}

df = pd.read_excel("large_file.xlsx", dtype=dtype_dict)

五、实战案例:销售数据整合

假设有以下需求:

  • 合并2023年各月销售数据(每月一个Excel文件)
  • 各月字段略有不同
  • 需要计算总销售额并分析趋势
import pandas as pd
import glob

# 1. 读取并合并数据
sales_files = glob.glob("sales_2023_*.xlsx")
all_sales = []

for file in sales_files:
    df = pd.read_excel(file)

    # 统一列名
    df.columns = df.columns.str.lower().str.replace(" ", "_")

    # 确保必要列存在
    if 'sales_amount' not in df.columns:
        if 'amount' in df.columns:
            df = df.rename(columns={'amount': 'sales_amount'})
        else:
            df['sales_amount'] = 0  # 默认值

    df['month'] = file.split('_')[-1].replace('.xlsx', '')
    all_sales.append(df)

# 合并数据
combined_sales = pd.concat(all_sales, ignore_index=True)

# 2. 数据清洗
combined_sales['sales_amount'] = pd.to_numeric(
    combined_sales['sales_amount'], 
    errors='coerce'
).fillna(0)

# 3. 分析月销售额
monthly_sales = combined_sales.groupby('month')['sales_amount'].sum()
monthly_sales.plot(kind='bar', title='Monthly Sales 2023')

# 4. 保存结果
with pd.ExcelWriter('sales_report_2023.xlsx') as writer:
    combined_sales.to_excel(writer, sheet_name='All Data', index=False)
    monthly_sales.to_excel(writer, sheet_name='Monthly Summary')

六、常见问题解决方案

1. 处理编码问题

# 尝试不同编码
try:
    df = pd.read_excel("data.xlsx")
except UnicodeDecodeError:
    df = pd.read_excel("data.xlsx", encoding='gbk')  # 中文常见编码

2. 跳过非数据行

# 跳过前3行非表头数据
df = pd.read_excel("file.xlsx", skiprows=3)

3. 处理合并时的重复数据

# 标记重复行
combined_df['is_duplicate'] = combined_df.duplicated()

# 或直接删除完全重复的行
combined_df = combined_df.drop_duplicates()

# 基于关键列去重
combined_df = combined_df.drop_duplicates(subset=['id', 'date'])

4. 处理Excel中的日期格式

# 读取时指定日期列
df = pd.read_excel("file.xlsx", parse_dates=['order_date'])

# 或读取后转换
df['order_date'] = pd.to_datetime(df['order_date'], errors='coerce')

七、最佳实践建议

  1. 文件检查:合并前先检查各文件结构,可使用pd.read_excel(file, nrows=5)预览
  2. 日志记录:记录合并过程中的文件读取情况
  3. 异常处理:捕获并处理可能的读取错误
  4. 内存监控:处理大文件时监控内存使用情况
  5. 版本兼容:注意openpyxlxlrd引擎的版本兼容性

通过本指南,您应该已经掌握了使用Pandas合并Excel文件的各种技术。根据您的具体需求选择合适的方法,简单的纵向合并使用pd.concat,复杂的关联合并使用pd.merge,大数据量场景考虑分块处理或格式转换。

,

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注