🎬 HoRain云小助手个人主页

 🔥 个人专栏: 《Linux 系列教程》《c语言教程

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

专栏介绍

专栏名称

专栏介绍

《C语言》

本专栏主要撰写C干货内容和编程技巧,让大家从底层了解C,把更多的知识由抽象到简单通俗易懂。

《网络协议》

本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘,一起解密网络协议在运行中协议的基本运行机制!

《docker容器精解篇》

全面深入解析 docker 容器,从基础到进阶,涵盖原理、操作、实践案例,助您精通 docker。

《linux系列》

本专栏主要撰写Linux干货内容,从基础到进阶,知识由抽象到简单通俗易懂,帮你从新手小白到扫地僧。

《python 系列》

本专栏着重撰写Python相关的干货内容与编程技巧,助力大家从底层去认识Python,将更多复杂的知识由抽象转化为简单易懂的内容。

《试题库》

本专栏主要是发布一些考试和练习题库(涵盖软考、HCIE、HRCE、CCNA等)

目录

⛳️ 推荐

专栏介绍

Pandas Excel 文件操作完全指南

📊 功能对比总览

🚀 一、环境准备与安装

1.1 安装必要库

1.2 各引擎对比

📖 二、读取 Excel 文件

2.1 基础读取

2.2 读取多个工作表

2.3 读取大文件(分块处理)

💾 三、写入 Excel 文件

3.1 基础写入

3.2 写入多个工作表

3.3 设置 Excel 样式

🔧 四、高级操作与技巧

4.1 处理多个 Excel 文件

4.2 数据清洗与转换

4.3 使用 openpyxl 高级功能

📈 五、性能优化技巧

5.1 读取优化

5.2 写入优化

🎯 六、实战案例

6.1 财务报表生成器

6.2 销售数据分析仪表板

⚠️ 七、常见问题与解决方案

7.1 中文编码问题

7.2 大型文件处理

7.3 错误处理

💡 最佳实践总结

1. 性能优化清单

2. 代码可读性建议

3. 文件管理建议


img

Pandas Excel 文件操作完全指南

Pandas 是 Python 中处理 Excel 文件的瑞士军刀,功能强大且灵活。下面我将从基础到高级,全面介绍如何使用 Pandas 操作 Excel 文件。

📊 功能对比总览

功能

方法/参数

适用场景

优点

限制

读取 Excel

pd.read_excel()

加载 Excel 数据

支持多种格式,灵活配置

大型文件较慢

写入 Excel

to_excel()

保存 DataFrame 到 Excel

格式保留,支持多工作表

内存占用较大

指定工作表

sheet_name

读取/写入特定表

精准控制目标表

默认第一个表

行列选择

usecols, skiprows

读取部分数据

提高读取效率

需知道列位置

数据类型

dtype

指定列数据类型

避免类型推断错误

需提前知道类型

多文件操作

ExcelFile对象

批量读取多个表

避免重复读取

一次性加载

样式设置

通过引擎设置

基本样式控制

简单美化

功能有限

🚀 一、环境准备与安装

1.1 安装必要库

# 基础安装
pip install pandas openpyxl xlrd

# 完整安装(包含所有引擎和功能)
pip install pandas openpyxl xlrd xlsxwriter odfpy

# 使用 conda
conda install pandas openpyxl xlrd

1.2 各引擎对比

引擎

支持格式

功能特点

适用场景

openpyxl

.xlsx, .xlsm, .xltx, .xltm

读写,支持公式、图表、样式

现代 Excel 文件

xlrd

.xls

只读,性能较好

旧版 .xls 文件

xlsxwriter

.xlsx

只写,功能丰富

生成复杂 Excel

odf

.ods, .odt

OpenDocument 格式

LibreOffice 文件

📖 二、读取 Excel 文件

2.1 基础读取

import pandas as pd
import numpy as np
from pathlib import Path

# 基本读取
def basic_read_excel():
    """基础读取示例"""
    # 读取整个 Excel 文件
    df = pd.read_excel('data.xlsx')
    
    # 显示基本信息
    print("数据形状:", df.shape)
    print("\n前5行数据:")
    print(df.head())
    
    # 显示列名
    print("\n列名:", df.columns.tolist())
    
    # 显示数据类型
    print("\n数据类型:")
    print(df.dtypes)
    
    return df

# 高级参数读取
def advanced_read_excel():
    """高级读取参数示例"""
    # 完整参数读取
    df = pd.read_excel(
        'data.xlsx',
        sheet_name=0,           # 工作表名称或索引
        header=0,               # 表头行(0-indexed)
        names=['Col1', 'Col2', 'Col3'],  # 自定义列名
        index_col=0,            # 将第一列设为索引
        usecols='A:C,E',        # 读取特定列
        skiprows=3,             # 跳过前3行
        nrows=100,              # 只读取前100行
        dtype={'Column1': str, 'Column2': float},  # 指定数据类型
        na_values=['NA', 'N/A', ''],  # 指定缺失值表示
        keep_default_na=True,   # 保持默认缺失值识别
        converters={'Column3': lambda x: x.upper()},  # 列转换函数
        engine='openpyxl',      # 指定引擎
        squeeze=False,          # 如果只有一列,返回Series
        thousands=',',          # 千分位分隔符
        comment='#',            # 注释字符
        skipfooter=0,           # 跳过底部行数
        parse_dates=['DateColumn'],  # 解析日期列
        date_parser=None,       # 日期解析函数
        thousands=None,         # 千分位分隔符
        decimal='.',            # 小数分隔符
    )
    
    return df

2.2 读取多个工作表

def read_multiple_sheets():
    """读取多个工作表"""
    # 方法1:读取所有表,返回字典
    all_sheets = pd.read_excel('data.xlsx', sheet_name=None)
    
    for sheet_name, df in all_sheets.items():
        print(f"工作表 '{sheet_name}' 形状: {df.shape}")
    
    # 方法2:读取指定表
    df1 = pd.read_excel('data.xlsx', sheet_name='Sheet1')
    df2 = pd.read_excel('data.xlsx', sheet_name=1)  # 第二个表
    
    # 方法3:读取部分表
    selected_sheets = pd.read_excel('data.xlsx', sheet_name=[0, 2])
    
    return all_sheets

# 使用 ExcelFile 对象(性能更好)
def read_with_excelfile():
    """使用 ExcelFile 对象提高效率"""
    xls = pd.ExcelFile('data.xlsx')
    
    # 查看所有工作表
    print("所有工作表:", xls.sheet_names)
    
    # 读取特定表
    df1 = pd.read_excel(xls, 'Sheet1')
    df2 = pd.read_excel(xls, 1)
    
    # 使用 parse 方法
    df3 = xls.parse('Sheet3')
    
    return xls, df1, df2, df3

2.3 读取大文件(分块处理)

def read_large_excel_chunks():
    """分块读取大文件"""
    chunk_size = 10000
    chunks = []
    
    # 使用 chunksize 参数
    for chunk in pd.read_excel('large_data.xlsx', chunksize=chunk_size):
        # 处理每个块
        processed_chunk = process_chunk(chunk)
        chunks.append(processed_chunk)
    
    # 合并所有块
    df = pd.concat(chunks, ignore_index=True)
    
    return df

def process_chunk(chunk):
    """处理数据块"""
    # 示例处理:删除缺失值超过50%的行
    threshold = len(chunk.columns) * 0.5
    chunk = chunk.dropna(thresh=threshold)
    
    return chunk

💾 三、写入 Excel 文件

3.1 基础写入

def basic_write_excel():
    """基础写入示例"""
    # 创建示例数据
    data = {
        '姓名': ['张三', '李四', '王五', '赵六'],
        '年龄': [25, 30, 35, 28],
        '城市': ['北京', '上海', '广州', '深圳'],
        '工资': [50000, 60000, 55000, 45000]
    }
    
    df = pd.DataFrame(data)
    
    # 基本写入
    df.to_excel('output.xlsx', index=False)  # 不写入索引列
    
    # 完整参数写入
    df.to_excel(
        'output.xlsx',
        sheet_name='员工信息',  # 工作表名称
        index=True,            # 是否包含索引
        header=True,           # 是否包含表头
        startrow=1,            # 起始行
        startcol=1,            # 起始列
        na_rep='N/A',          # 缺失值表示
        float_format='%.2f',   # 浮点数格式
        columns=['姓名', '年龄', '工资'],  # 指定列顺序
        encoding='utf-8-sig',  # 编码(支持中文)
        inf_rep='inf',         # 无穷大表示
        engine='openpyxl',     # 写入引擎
    )
    
    return df

3.2 写入多个工作表

def write_multiple_sheets():
    """写入多个工作表到同一个文件"""
    # 创建多个 DataFrame
    df1 = pd.DataFrame({
        '产品': ['A', 'B', 'C'],
        '销量': [100, 200, 150]
    })
    
    df2 = pd.DataFrame({
        '月份': ['1月', '2月', '3月'],
        '收入': [50000, 60000, 55000]
    })
    
    # 方法1:使用 ExcelWriter
    with pd.ExcelWriter('reports.xlsx', engine='openpyxl') as writer:
        df1.to_excel(writer, sheet_name='产品销售', index=False)
        df2.to_excel(writer, sheet_name='月度收入', index=False)
        
        # 获取工作簿和工作表对象
        workbook = writer.book
        worksheet = writer.sheets['产品销售']
        
        # 可以进一步操作工作簿(如设置列宽)
        worksheet.column_dimensions['A'].width = 20
    
    # 方法2:追加到现有文件
    with pd.ExcelWriter('reports.xlsx', engine='openpyxl', mode='a') as writer:
        df3 = pd.DataFrame({'新数据': [1, 2, 3]})
        df3.to_excel(writer, sheet_name='新表', index=False)
    
    return df1, df2

3.3 设置 Excel 样式

def write_with_styling():
    """写入时设置基本样式"""
    data = {
        '部门': ['技术部', '市场部', '销售部', '人事部'],
        '预算': [100000, 80000, 120000, 50000],
        '实际支出': [95000, 85000, 110000, 48000]
    }
    
    df = pd.DataFrame(data)
    
    with pd.ExcelWriter('styled_report.xlsx', engine='xlsxwriter') as writer:
        df.to_excel(writer, sheet_name='预算报告', index=False)
        
        # 获取工作簿和工作表对象
        workbook = writer.book
        worksheet = writer.sheets['预算报告']
        
        # 定义格式
        header_format = workbook.add_format({
            'bold': True,
            'text_wrap': True,
            'valign': 'top',
            'fg_color': '#D7E4BD',
            'border': 1
        })
        
        money_format = workbook.add_format({'num_format': '#,##0'})
        percent_format = workbook.add_format({'num_format': '0.00%'})
        
        # 应用表头格式
        for col_num, value in enumerate(df.columns.values):
            worksheet.write(0, col_num, value, header_format)
        
        # 设置列宽
        worksheet.set_column('A:A', 20)
        worksheet.set_column('B:C', 15, money_format)
        
        # 添加公式列
        worksheet.write(0, 3, '完成率')
        for row in range(1, len(df) + 1):
            formula = f'=C{row+1}/B{row+1}'  # 实际支出/预算
            worksheet.write_formula(row, 3, formula, percent_format)
        
        # 添加条件格式
        worksheet.conditional_format('D2:D5', {
            'type': 'data_bar',
            'bar_color': '#63C384'
        })
    
    return df

🔧 四、高级操作与技巧

4.1 处理多个 Excel 文件

from pathlib import Path
import glob

def process_multiple_files():
    """批量处理多个 Excel 文件"""
    # 查找所有 Excel 文件
    excel_files = glob.glob('data/*.xlsx')
    
    all_data = []
    
    for file in excel_files:
        try:
            # 读取文件
            df = pd.read_excel(file)
            
            # 添加文件名列
            df['源文件'] = Path(file).name
            
            all_data.append(df)
            
        except Exception as e:
            print(f"读取文件 {file} 时出错: {e}")
    
    # 合并所有数据
    if all_data:
        combined_df = pd.concat(all_data, ignore_index=True)
        return combined_df
    
    return pd.DataFrame()

# 读取文件夹下所有文件
def read_all_excel_in_folder(folder_path):
    """读取文件夹下所有 Excel 文件"""
    data_frames = {}
    
    folder = Path(folder_path)
    for excel_file in folder.glob('*.xls*'):
        # 读取所有工作表
        sheets = pd.read_excel(excel_file, sheet_name=None)
        
        for sheet_name, df in sheets.items():
            # 使用文件名和工作表名作为键
            key = f"{excel_file.stem}_{sheet_name}"
            data_frames[key] = df
    
    return data_frames

4.2 数据清洗与转换

def excel_data_cleaning():
    """Excel 数据清洗与转换"""
    # 读取数据
    df = pd.read_excel('dirty_data.xlsx')
    
    print("原始数据形状:", df.shape)
    
    # 1. 处理缺失值
    # 删除全为 NaN 的行
    df = df.dropna(how='all')
    
    # 删除全为 NaN 的列
    df = df.dropna(axis=1, how='all')
    
    # 填充缺失值
    df['数值列'] = df['数值列'].fillna(df['数值列'].mean())
    df['文本列'] = df['文本列'].fillna('未知')
    
    # 2. 数据类型转换
    df['日期列'] = pd.to_datetime(df['日期列'], errors='coerce')
    df['数值列'] = pd.to_numeric(df['数值列'], errors='coerce')
    
    # 3. 重复数据处理
    # 标记重复行
    df['是否重复'] = df.duplicated(subset=['关键列1', '关键列2'], keep=False)
    
    # 删除完全重复的行
    df = df.drop_duplicates()
    
    # 4. 异常值处理
    # 使用 IQR 方法检测异常值
    Q1 = df['数值列'].quantile(0.25)
    Q3 = df['数值列'].quantile(0.75)
    IQR = Q3 - Q1
    
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    
    # 标记异常值
    df['是否异常'] = (df['数值列'] < lower_bound) | (df['数值列'] > upper_bound)
    
    # 5. 数据标准化
    from sklearn.preprocessing import StandardScaler
    
    scaler = StandardScaler()
    df[['标准化数值1', '标准化数值2']] = scaler.fit_transform(
        df[['数值列1', '数值列2']]
    )
    
    # 6. 分类数据编码
    df['编码列'] = pd.factorize(df['分类列'])[0]
    
    return df

4.3 使用 openpyxl 高级功能

from openpyxl import load_workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.utils import get_column_letter

def enhance_excel_with_openpyxl():
    """使用 openpyxl 增强 Excel 功能"""
    # 首先用 pandas 写入数据
    data = {
        '月份': ['1月', '2月', '3月', '4月'],
        '销售额': [10000, 15000, 12000, 18000],
        '成本': [6000, 8000, 7000, 9000]
    }
    
    df = pd.DataFrame(data)
    df.to_excel('enhanced_report.xlsx', index=False)
    
    # 使用 openpyxl 打开文件并修改
    wb = load_workbook('enhanced_report.xlsx')
    ws = wb.active
    
    # 设置表头样式
    header_fill = PatternFill(
        start_color="366092", 
        end_color="366092", 
        fill_type="solid"
    )
    
    header_font = Font(color="FFFFFF", bold=True)
    header_alignment = Alignment(horizontal="center", vertical="center")
    
    for cell in ws[1]:
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = header_alignment
    
    # 设置数值格式
    money_format = '#,##0'
    for row in ws.iter_rows(min_row=2, min_col=2, max_col=3):
        for cell in row:
            cell.number_format = money_format
    
    # 计算利润(添加新列)
    ws['D1'] = '利润'
    for row in range(2, ws.max_row + 1):
        ws[f'D{row}'] = f'=B{row}-C{row}'
        ws[f'D{row}'].number_format = money_format
    
    # 设置列宽
    for column in ws.columns:
        max_length = 0
        column_letter = get_column_letter(column[0].column)
        
        for cell in column:
            try:
                if len(str(cell.value)) > max_length:
                    max_length = len(str(cell.value))
            except:
                pass
        
        adjusted_width = min(max_length + 2, 30)
        ws.column_dimensions[column_letter].width = adjusted_width
    
    # 添加汇总行
    summary_row = ws.max_row + 2
    ws[f'A{summary_row}'] = '总计'
    ws[f'B{summary_row}'] = f'=SUM(B2:B{ws.max_row-1})'
    ws[f'C{summary_row}'] = f'=SUM(C2:C{ws.max_row-1})'
    ws[f'D{summary_row}'] = f'=SUM(D2:D{ws.max_row-1})'
    
    # 设置总计行样式
    total_fill = PatternFill(
        start_color="C6E0B4", 
        end_color="C6E0B4", 
        fill_type="solid"
    )
    
    for cell in ws[summary_row]:
        cell.fill = total_fill
        cell.font = Font(bold=True)
    
    # 保存文件
    wb.save('enhanced_report.xlsx')

📈 五、性能优化技巧

5.1 读取优化

def optimize_read_performance():
    """优化读取性能"""
    import time
    
    start_time = time.time()
    
    # 优化技巧1:只读取需要的列
    df = pd.read_excel('large_file.xlsx', 
                      usecols=['必要列1', '必要列2', '必要列3'])
    
    # 优化技巧2:指定数据类型,减少内存使用
    dtypes = {
        '整数列': 'int32',
        '小数列': 'float32',
        '字符串列': 'category'  # 分类数据使用category类型
    }
    
    df = pd.read_excel('large_file.xlsx', dtype=dtypes)
    
    # 优化技巧3:跳过不必要的行
    df = pd.read_excel('large_file.xlsx', skiprows=range(1, 1000))
    
    # 优化技巧4:使用chunksize分块处理
    chunks = []
    for chunk in pd.read_excel('large_file.xlsx', chunksize=10000):
        # 处理每个块
        chunk = process_chunk(chunk)
        chunks.append(chunk)
    
    if chunks:
        df = pd.concat(chunks, ignore_index=True)
    
    elapsed_time = time.time() - start_time
    print(f"读取完成,用时: {elapsed_time:.2f}秒")
    
    return df

5.2 写入优化

def optimize_write_performance():
    """优化写入性能"""
    import time
    
    # 创建大型 DataFrame
    df = pd.DataFrame({
        'A': np.random.randn(1000000),
        'B': np.random.randint(0, 100, 1000000),
        'C': ['text'] * 1000000
    })
    
    start_time = time.time()
    
    # 优化技巧1:使用 xlsxwriter 引擎(写入性能较好)
    df.to_excel('large_output.xlsx', engine='xlsxwriter', index=False)
    
    # 优化技巧2:分块写入
    with pd.ExcelWriter('chunked_output.xlsx', engine='xlsxwriter') as writer:
        chunk_size = 100000
        for i in range(0, len(df), chunk_size):
            chunk = df.iloc[i:i+chunk_size]
            sheet_name = f'Chunk_{i//chunk_size + 1}'
            chunk.to_excel(writer, sheet_name=sheet_name, index=False)
    
    elapsed_time = time.time() - start_time
    print(f"写入完成,用时: {elapsed_time:.2f}秒")

🎯 六、实战案例

6.1 财务报表生成器

class FinancialReportGenerator:
    """财务报表生成器"""
    
    def __init__(self, data_path):
        self.data_path = data_path
        self.report_data = None
    
    def load_and_process(self):
        """加载和处理数据"""
        # 读取原始数据
        df = pd.read_excel(self.data_path, sheet_name='原始数据')
        
        # 数据清洗
        df = self.clean_data(df)
        
        # 计算财务指标
        df = self.calculate_financial_metrics(df)
        
        self.report_data = df
        return df
    
    def clean_data(self, df):
        """数据清洗"""
        # 删除空行
        df = df.dropna(how='all')
        
        # 统一日期格式
        df['日期'] = pd.to_datetime(df['日期'])
        
        # 处理缺失值
        numeric_cols = df.select_dtypes(include=[np.number]).columns
        df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].mean())
        
        # 去除重复
        df = df.drop_duplicates()
        
        return df
    
    def calculate_financial_metrics(self, df):
        """计算财务指标"""
        # 按月汇总
        monthly = df.groupby(pd.Grouper(key='日期', freq='M')).agg({
            '收入': 'sum',
            '成本': 'sum',
            '费用': 'sum'
        }).reset_index()
        
        # 计算指标
        monthly['毛利润'] = monthly['收入'] - monthly['成本']
        monthly['毛利率'] = monthly['毛利润'] / monthly['收入']
        monthly['净利润'] = monthly['收入'] - monthly['成本'] - monthly['费用']
        monthly['净利率'] = monthly['净利润'] / monthly['收入']
        
        return monthly
    
    def generate_report(self, output_path):
        """生成报表"""
        if self.report_data is None:
            self.load_and_process()
        
        with pd.ExcelWriter(output_path, engine='xlsxwriter') as writer:
            # 写入月度汇总
            self.report_data.to_excel(
                writer, 
                sheet_name='月度汇总', 
                index=False
            )
            
            # 创建详细报告
            workbook = writer.book
            worksheet = writer.sheets['月度汇总']
            
            # 添加图表
            chart = workbook.add_chart({'type': 'line'})
            
            # 配置图表
            chart.add_series({
                'name': '收入',
                'categories': '=月度汇总!$A$2:$A${}'.format(len(self.report_data)+1),
                'values': '=月度汇总!$B$2:$B${}'.format(len(self.report_data)+1),
            })
            
            chart.add_series({
                'name': '净利润',
                'categories': '=月度汇总!$A$2:$A${}'.format(len(self.report_data)+1),
                'values': '=月度汇总!$F$2:$F${}'.format(len(self.report_data)+1),
            })
            
            chart.set_title({'name': '财务趋势分析'})
            chart.set_x_axis({'name': '日期'})
            chart.set_y_axis({'name': '金额'})
            
            # 插入图表
            worksheet.insert_chart('H2', chart)
            
            # 创建第二个工作表:年度汇总
            annual = self.report_data.copy()
            annual['年份'] = annual['日期'].dt.year
            annual_summary = annual.groupby('年份').agg({
                '收入': 'sum',
                '净利润': 'sum'
            }).reset_index()
            
            annual_summary.to_excel(
                writer, 
                sheet_name='年度汇总', 
                index=False
            )
        
        print(f"报表已生成: {output_path}")
    
    def batch_process(self, input_folder, output_folder):
        """批量处理多个文件"""
        import os
        from pathlib import Path
        
        input_path = Path(input_folder)
        output_path = Path(output_folder)
        output_path.mkdir(exist_ok=True)
        
        for excel_file in input_path.glob('*.xlsx'):
            print(f"处理文件: {excel_file.name}")
            
            # 更新数据路径
            self.data_path = excel_file
            
            # 生成报告
            output_file = output_path / f"report_{excel_file.stem}.xlsx"
            self.generate_report(output_file)

# 使用示例
if __name__ == "__main__":
    generator = FinancialReportGenerator('financial_data.xlsx')
    generator.generate_report('财务报告.xlsx')

6.2 销售数据分析仪表板

def create_sales_dashboard():
    """创建销售数据分析仪表板"""
    # 读取销售数据
    sales_df = pd.read_excel('sales_data.xlsx')
    
    with pd.ExcelWriter('sales_dashboard.xlsx', engine='xlsxwriter') as writer:
        # 1. 整体概览
        overview_df = pd.DataFrame({
            '指标': ['总销售额', '总订单数', '平均订单额', '客户数'],
            '数值': [
                sales_df['销售额'].sum(),
                sales_df['订单号'].nunique(),
                sales_df['销售额'].mean(),
                sales_df['客户ID'].nunique()
            ]
        })
        
        overview_df.to_excel(writer, sheet_name='概览', index=False)
        
        # 2. 按产品类别汇总
        category_sales = sales_df.groupby('产品类别').agg({
            '销售额': 'sum',
            '订单号': 'count',
            '利润': 'sum'
        }).reset_index()
        
        category_sales.to_excel(writer, sheet_name='按类别', index=False)
        
        # 3. 按月份趋势
        sales_df['月份'] = pd.to_datetime(sales_df['日期']).dt.to_period('M')
        monthly_trend = sales_df.groupby('月份').agg({
            '销售额': 'sum',
            '利润': 'sum'
        }).reset_index()
        
        monthly_trend.to_excel(writer, sheet_name='月度趋势', index=False)
        
        # 4. 客户分析
        customer_analysis = sales_df.groupby('客户ID').agg({
            '销售额': 'sum',
            '订单号': 'count',
            '利润': 'sum'
        }).reset_index()
        
        customer_analysis['客单价'] = customer_analysis['销售额'] / customer_analysis['订单号']
        customer_analysis.to_excel(writer, sheet_name='客户分析', index=False)
        
        # 获取工作簿对象
        workbook = writer.book
        
        # 创建概览表的格式化
        overview_sheet = writer.sheets['概览']
        
        # 定义格式
        money_format = workbook.add_format({'num_format': '#,##0.00'})
        int_format = workbook.add_format({'num_format': '#,##0'})
        
        # 应用格式
        overview_sheet.set_column('B:B', 15, money_format)
        
        # 添加条件格式突出显示
        overview_sheet.conditional_format('B2:B5', {
            'type': 'data_bar',
            'bar_color': '#63C384'
        })
        
    print("销售仪表板已生成")

⚠️ 七、常见问题与解决方案

7.1 中文编码问题

def handle_chinese_encoding():
    """处理中文编码问题"""
    try:
        # 方法1:指定编码
        df = pd.read_excel('中文文件.xlsx', encoding='utf-8-sig')
        
        # 方法2:使用引擎的编码参数
        df = pd.read_excel('中文文件.xlsx', engine='openpyxl')
        
        # 写入时指定编码
        df.to_excel('输出.xlsx', encoding='utf-8-sig', index=False)
        
    except UnicodeDecodeError as e:
        print(f"编码错误: {e}")
        
        # 尝试其他编码
        encodings = ['gbk', 'gb2312', 'gb18030', 'latin1']
        
        for encoding in encodings:
            try:
                df = pd.read_excel('中文文件.xlsx', encoding=encoding)
                print(f"使用 {encoding} 编码成功")
                break
            except:
                continue

7.2 大型文件处理

def handle_large_excel_file():
    """处理大型 Excel 文件"""
    # 1. 监控内存使用
    import psutil
    import os
    
    process = psutil.Process(os.getpid())
    print(f"当前内存使用: {process.memory_info().rss / 1024 / 1024:.2f} MB")
    
    # 2. 分块读取和处理
    chunk_size = 10000
    processed_chunks = []
    
    for chunk in pd.read_excel('large_file.xlsx', chunksize=chunk_size):
        # 处理每个块
        processed = process_chunk_memory_efficient(chunk)
        processed_chunks.append(processed)
        
        # 清理内存
        del chunk
        import gc
        gc.collect()
    
    # 3. 合并结果
    if processed_chunks:
        result = pd.concat(processed_chunks, ignore_index=True)
    
    # 4. 保存时压缩
    result.to_excel('output.xlsx', index=False, compression='zip')
    
    return result

def process_chunk_memory_efficient(chunk):
    """内存高效的数据块处理"""
    # 使用更高效的数据类型
    for col in chunk.select_dtypes(include=['float64']).columns:
        chunk[col] = chunk[col].astype('float32')
    
    for col in chunk.select_dtypes(include=['int64']).columns:
        chunk[col] = chunk[col].astype('int32')
    
    for col in chunk.select_dtypes(include=['object']).columns:
        if chunk[col].nunique() / len(chunk) < 0.5:  # 分类数据
            chunk[col] = chunk[col].astype('category')
    
    return chunk

7.3 错误处理

def safe_excel_operations():
    """安全的 Excel 操作"""
    try:
        # 读取操作
        df = pd.read_excel('data.xlsx')
        
        # 数据处理
        result = df.groupby('category').sum()
        
        # 写入操作
        with pd.ExcelWriter('output.xlsx', engine='openpyxl') as writer:
            result.to_excel(writer, sheet_name='汇总')
            
    except FileNotFoundError as e:
        print(f"文件不存在: {e}")
        
    except pd.errors.EmptyDataError as e:
        print(f"Excel 文件为空: {e}")
        
    except pd.errors.ParserError as e:
        print(f"解析 Excel 文件出错: {e}")
        
    except KeyError as e:
        print(f"缺少必要的列: {e}")
        
    except ValueError as e:
        print(f"数据值错误: {e}")
        
    except Exception as e:
        print(f"未知错误: {e}")
        import traceback
        traceback.print_exc()
    
    finally:
        print("操作完成")

💡 最佳实践总结

1. 性能优化清单

  • [ ] 只读取需要的列(usecols参数)

  • [ ] 指定数据类型(dtype参数)

  • [ ] 跳过不必要的行(skiprows参数)

  • [ ] 使用分块读取大文件(chunksize参数)

  • [ ] 使用 ExcelFile对象读取多个表

  • [ ] 写入时使用 xlsxwriter引擎提高性能

  • [ ] 清理不需要的变量释放内存

2. 代码可读性建议

# 好的实践
def process_excel_data(file_path, sheet_name='Sheet1'):
    """
    处理 Excel 数据
    
    Args:
        file_path: Excel 文件路径
        sheet_name: 工作表名称
    
    Returns:
        DataFrame: 处理后的数据
    """
    # 读取配置
    read_config = {
        'sheet_name': sheet_name,
        'usecols': 'A:D',  # 只读取需要的列
        'dtype': {'ID': 'int32', 'Value': 'float32'},
        'parse_dates': ['Date']
    }
    
    # 读取数据
    df = pd.read_excel(file_path, **read_config)
    
    # 数据清洗
    df_cleaned = clean_data(df)
    
    return df_cleaned

# 不好的实践
def process(file):
    df = pd.read_excel(file)  # 没有参数说明
    df = df.dropna()  # 没有说明原因
    return df

3. 文件管理建议

# 使用 pathlib 管理文件路径
from pathlib import Path
import pandas as pd

def process_excel_files(data_folder, output_folder):
    """处理 Excel 文件,使用 pathlib 管理路径"""
    data_dir = Path(data_folder)
    output_dir = Path(output_folder)
    
    # 确保输出目录存在
    output_dir.mkdir(parents=True, exist_ok=True)
    
    # 遍历所有 Excel 文件
    for excel_file in data_dir.glob('*.xlsx'):
        print(f"处理文件: {excel_file.name}")
        
        try:
            # 读取数据
            df = pd.read_excel(excel_file)
            
            # 处理数据
            processed_df = process_data(df)
            
            # 保存结果
            output_file = output_dir / f"processed_{excel_file.name}"
            processed_df.to_excel(output_file, index=False)
            
            print(f"✓ 完成: {output_file}")
            
        except Exception as e:
            print(f"✗ 处理失败: {excel_file.name}, 错误: {e}")

通过掌握这些 Pandas Excel 操作技巧,您可以高效地处理各种 Excel 数据处理任务。记住关键原则:读取时尽量精确,处理时注意性能,写入时保持格式清晰

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐