如何使用 Pandas 读取 Excel 数据 – wiki基地


掌握数据导入的基石:使用 Pandas 库高效读取 Excel 文件

在现代数据分析、数据科学以及日常的数据处理工作中,Excel 文件(.xls.xlsx)仍然是最常见的数据存储和交换格式之一。无论是业务报告、实验数据、用户列表还是任何表格形式的信息,都可能以 Excel 的形式呈现。然而,Excel 本身的分析能力相对有限,尤其是处理大规模数据、进行复杂计算或自动化流程时。这时,强大的 Python 库 Pandas 就显得至关重要了。

Pandas 提供了高性能、易于使用的数据结构(如 DataFrame)和数据分析工具。它能够无缝地与各种数据源交互,其中就包括对 Excel 文件的读写支持。掌握如何使用 Pandas 读取 Excel 文件,是利用 Python 进行数据处理和分析的第一步,也是至关重要的一步。

本文将深入探讨如何使用 Pandas 库中的核心函数 read_excel() 来读取 Excel 数据。我们将从最基本的用法开始,逐步深入到各种高级选项,涵盖处理不同格式、结构复杂的 Excel 文件时可能遇到的各种情况。通过详尽的解释和丰富的代码示例,帮助你全面掌握这一技能。

1. 为什么选择 Pandas 读取 Excel?

在深入技术细节之前,我们先快速回顾一下为什么 Pandas 是读取和处理 Excel 数据的首选工具:

  • 强大的数据结构 (DataFrame): Pandas 将 Excel 的表格数据读取到其核心数据结构 DataFrame 中。DataFrame 类似于电子表格或 SQL 表,具有行和列标签,提供了丰富的数据操作方法(筛选、排序、分组、合并等),远超 Excel 内置功能。
  • 高效性能: Pandas 底层使用 C 语言编写,处理大规模数据时性能优异。对于百万行级别的数据,Pandas 的处理速度通常比直接在 Excel 中手动操作快得多。
  • 灵活性和自动化: 通过 Python 脚本,你可以完全自动化读取、清洗、转换和分析 Excel 数据的整个流程,无需手动打开和操作 Excel 文件,极大地提高了工作效率。
  • 与其他库的集成: Pandas 与 Python 生态系统中其他重要库(如 NumPy、Matplotlib、Seaborn、Scikit-learn 等)无缝集成,为你提供了从数据读取到可视化、建模的全套解决方案。
  • 处理复杂格式: Pandas read_excel 函数提供了大量参数,可以灵活应对 Excel 文件中存在的各种复杂情况,如多工作表、跳过行、指定列、处理合并单元格等。

2. 环境准备

在开始之前,请确保你的 Python 环境已经安装了 Pandas 以及用于读取 Excel 文件的依赖库。

首先,安装 Pandas:

bash
pip install pandas

Pandas 读取 .xlsx 文件通常依赖于 openpyxl 库(推荐)或 xlrd 库(老版本,对 .xlsx 支持有限,新版本已移除 .xlsx 支持)。对于 .xls 文件,通常需要 xlrd 库。而对于 .ods (OpenDocument Spreadsheet) 文件,需要 odfpy 库。对于 .xlsb (Excel Binary Workbook) 文件,需要 pyxlsb 库。

为了最大程度地兼容各种格式,建议同时安装以下库:

bash
pip install openpyxl xlrd odfpy pyxlsb

安装完成后,你就可以在 Python 脚本或 Jupyter Notebook 中导入 Pandas 并开始使用了。

python
import pandas as pd

3. pd.read_excel() 函数概览

pd.read_excel() 是 Pandas 中用于读取 Excel 文件的主要函数。它的基本语法如下:

python
pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None,
usecols=None, squeeze=False, dtype=None, engine=None,
converters=None, true_values=None, false_values=None,
skiprows=None, nrows=None, na_values=None,
parse_dates=False, date_parser=None, thousands=None,
comment=None, keep_default_na=True, verbose=False,
decimal='.', orient=None, storage_options=None, merge_cells=True,
dtype_backend=None)

这个函数有很多参数,但大部分都有合理的默认值。我们将逐步介绍其中最常用和最重要的参数。

最简单的用法是只指定文件路径:

“`python

假设当前目录下有一个名为 ‘my_data.xlsx’ 的 Excel 文件

df = pd.read_excel(‘my_data.xlsx’)
print(df.head())
“`

这将读取 Excel 文件中第一个工作表(默认 sheet_name=0),并将第一行(默认 header=0)作为列名,其余数据加载到 DataFrame 中。

接下来,我们将详细探讨如何利用 read_excel() 的各种参数来应对不同的读取需求。

4. 处理工作表 (Sheets)

一个 Excel 文件通常包含一个或多个工作表。read_excel() 函数通过 sheet_name 参数来指定要读取哪个工作表。

  • 读取第一个工作表 (默认行为):
    python
    df = pd.read_excel('my_data.xlsx') # 等同于 sheet_name=0

    或者显式指定索引 0:
    python
    df = pd.read_excel('my_data.xlsx', sheet_name=0)

  • 通过名称读取指定工作表:
    如果你的工作表有明确的名称(例如 ‘销售数据’),可以使用字符串作为 sheet_name 的值。
    python
    df_sales = pd.read_excel('my_report.xlsx', sheet_name='销售数据')
    print(df_sales.head())

    请注意,工作表名称是区分大小写的。

  • 读取多个工作表:
    你可以通过传递一个工作表名称(字符串)或索引(整数)的列表来同时读取多个工作表。此时,read_excel() 将返回一个字典,其中键是工作表名称,值是对应的 DataFrame。
    “`python
    # 读取工作表 ‘Sheet1’ 和 ‘Sheet3’
    sheet_list = [‘Sheet1’, ‘Sheet3’]
    data_dict = pd.read_excel(‘multi_sheet_data.xlsx’, sheet_name=sheet_list)

    data_dict 是一个字典,例如 {‘Sheet1’: df1, ‘Sheet3’: df3}

    df1 = data_dict[‘Sheet1’]
    df3 = data_dict[‘Sheet3’]

    print(“数据字典的键:”, data_dict.keys())
    print(“\nSheet1 的前几行:”)
    print(df1.head())
    print(“\nSheet3 的前几行:”)
    print(df3.head())
    “`

  • 读取所有工作表:
    sheet_name 设置为 None 将读取 Excel 文件中的所有工作表。同样,这将返回一个字典,键是工作表名称,值是对应的 DataFrame。
    “`python
    all_sheets_dict = pd.read_excel(‘full_report.xlsx’, sheet_name=None)

    遍历并打印所有工作表的数据

    for sheet_name, df in all_sheets_dict.items():
    print(f”\n— 工作表: {sheet_name} —“)
    print(df.head())
    print(f”行数: {len(df)}, 列数: {len(df.columns)}”)
    “`
    这种方式非常适合当你需要处理文件中所有数据,但它们被分散在不同的工作表中时。

5. 处理列名 (Headers)

Excel 文件中的列名(Header)可能并不总是在第一行,或者可能根本没有列名。header 参数用于指定哪一行作为列名。

  • 第一行作为列名 (默认行为):
    python
    df = pd.read_excel('data_with_header.xlsx', header=0) # header=0 是默认值

    这意味着第 0 行(也就是 Excel 中的第 1 行)将被用作列名,数据从第 1 行(Excel 中的第 2 行)开始读取。

  • 指定其他行作为列名:
    如果你的列名在 Excel 的第三行,那么在 Pandas 中对应的索引是 2(索引从 0 开始)。
    python
    df = pd.read_excel('data_header_row3.xlsx', header=2)

    此时,Excel 文件中的第 3 行将成为 DataFrame 的列名,第 0、1、2 行(Excel 中的第 1、2、3 行)将被跳过,数据从第 3 行(Excel 中的第 4 行)开始读取。

  • 文件没有列名:
    如果 Excel 文件没有明确的列名行,你可以将 header 参数设置为 None。Pandas 会自动生成从 0 开始的整数序列作为列名(0, 1, 2, …)。
    python
    df_no_header = pd.read_excel('data_no_header.xlsx', header=None)
    print(df_no_header.head())
    # 此时你可以手动为列命名
    # df_no_header.columns = ['colA', 'colB', 'colC', ...]

    这种情况下,数据将从文件的第一行开始读取。

  • 多层列名 (MultiIndex Header):
    如果你的 Excel 文件有两行或多行共同构成列名(例如,年份-季度,地区-产品),你可以传递一个整数列表给 header 参数。这将创建一个多层索引(MultiIndex)作为 DataFrame 的列名。
    python
    # 假设 Excel 中第 1 行是年份,第 2 行是季度
    df_multi_header = pd.read_excel('data_multi_header.xlsx', header=[0, 1])
    print(df_multi_header.head())
    print(df_multi_header.columns) # 查看多层列名结构

  • 使用 names 参数手动指定列名:
    无论原始文件是否有列名行,你都可以使用 names 参数强制指定 DataFrame 的列名。这通常与 header=None 一起使用。
    python
    # 假设文件没有列名,但你知道列的含义
    new_column_names = ['ID', 'Name', 'Value', 'Category']
    df_renamed = pd.read_excel('data_no_header.xlsx', header=None, names=new_column_names)
    print(df_renamed.head())

6. 设置索引列 (Index Column)

DataFrame 可以有一个或多个索引列,用于唯一标识行(类似于数据库中的主键)。read_excel() 函数通过 index_col 参数来指定哪一列或哪几列作为 DataFrame 的索引。

  • 不设置索引 (默认行为):
    python
    df = pd.read_excel('my_data.xlsx', index_col=None) # index_col=None 是默认值

    Pandas 会自动生成一个从 0 开始的整数序列作为行索引。

  • 指定单列作为索引:
    可以通过列的索引(从 0 开始)或列名来指定索引列。
    “`python
    # 使用列索引(假设第二列,索引为 1,是 ID 列)
    df_indexed_by_col1 = pd.read_excel(‘data_with_id.xlsx’, index_col=1)
    print(df_indexed_by_col1.head())

    使用列名(假设 ‘ID’ 列是索引列)

    df_indexed_by_name = pd.read_excel(‘data_with_id.xlsx’, index_col=’ID’)
    print(df_indexed_by_name.head())
    “`

  • 指定多列作为复合索引 (MultiIndex Index):
    类似于多层列名,你也可以通过传递一个列索引或列名列表来创建多层行索引。
    python
    # 假设前两列 (索引 0 和 1) 组合起来构成唯一标识
    df_multi_index = pd.read_excel('data_composite_key.xlsx', index_col=[0, 1])
    print(df_multi_index.head())
    print(df_multi_index.index) # 查看多层行索引结构

  • 禁止将第一列作为默认索引:
    有时候 Excel 文件的第一列可能看起来像索引,但你并不想让 Pandas 将其自动识别为索引。在某些 Pandas 版本和特定的 Excel 文件结构下,可能会出现这种情况。你可以通过明确设置 index_col=None 来避免:
    python
    df = pd.read_excel('potentially_indexed_data.xlsx', index_col=None)
    print(df.head())

7. 跳过行和限制行数

有时 Excel 文件在数据表格之前或之后包含一些描述性文本、标题或摘要行,或者你只对文件开头的一部分数据感兴趣。skiprowsnrows 参数可以帮助你精确控制读取哪些行。

  • 跳过开头的指定行数:
    使用整数作为 skiprows 的值,可以跳过文件开头的指定行数。
    python
    # 跳过文件开头的 5 行
    df = pd.read_excel('data_with_intro.xlsx', skiprows=5)
    print(df.head())

    请注意,skiprows 是在处理 header 之前生效的。如果你跳过了 5 行,并且 header=0(默认),那么 Pandas 会在跳过 5 行后的第一行(原文件的第 6 行)寻找列名。

  • 跳过特定的行号:
    可以使用一个列表来指定要跳过的具体行号(从 0 开始计数)。
    python
    # 跳过文件中的第 0, 2, 3 行
    df = pd.read_excel('data_skip_specific.xlsx', skiprows=[0, 2, 3])
    print(df.head())

  • 限制读取的行数:
    使用 nrows 参数可以指定从数据开始的地方(经过 skiprowsheader 处理后)读取多少行数据。这对于处理非常大的文件,只想查看前几行进行初步检查时非常有用。
    python
    # 只读取数据的前 100 行
    df_sample = pd.read_excel('large_dataset.xlsx', nrows=100)
    print(df_sample)

  • 结合使用 skiprowsnrows:
    你可以结合使用这两个参数来精确选择读取的数据范围。例如,跳过开头的 10 行,然后从第 11 行开始读取 50 行。
    python
    df_slice = pd.read_excel('large_dataset.xlsx', skiprows=10, nrows=50)
    print(df_slice)

8. 选择指定的列

你可能只需要 Excel 文件中的部分列,而不是全部。usecols 参数允许你指定要读取哪些列。这不仅可以减少内存使用,还可以加快读取速度。

  • 使用列索引选择列:
    传递一个列索引(从 0 开始)的列表。
    python
    # 只读取第一列 (索引 0) 和第三列 (索引 2)
    df_subset_by_index = pd.read_excel('my_data.xlsx', usecols=[0, 2])
    print(df_subset_by_index.head())

  • 使用列名选择列:
    传递一个列名的字符串列表。
    python
    # 只读取 'ProductName' 和 'SalesAmount' 列
    df_subset_by_name = pd.read_excel('sales_data.xlsx', usecols=['ProductName', 'SalesAmount'])
    print(df_subset_by_name.head())

    请注意,使用列名时,Pandas 首先会读取文件的 header 行来获取列名,然后再根据这些列名选择数据。

  • 使用列的字母表示:
    你也可以使用 Excel 中列的字母表示(如 ‘A’, ‘C’, ‘AZ’)。
    “`python
    # 读取 Excel 中的 A 列和 C 列
    df_subset_by_letters = pd.read_excel(‘my_data.xlsx’, usecols=’A,C’)
    print(df_subset_by_letters.head())

    读取 Excel 中的 A 到 C 列

    df_subset_range = pd.read_excel(‘my_data.xlsx’, usecols=’A:C’)
    print(df_subset_range.head())
    “`
    这种方式通常用于简单的列选择,对于复杂的选择,建议使用索引或列名列表。

  • 使用可调用对象选择列:
    usecols 还可以接受一个函数,该函数会接收列名(字符串)并返回布尔值,True 表示选择该列,False 表示跳过。这对于根据某种模式选择列非常有用。
    python
    # 选择所有列名中包含 'Amount' 的列
    df_filtered_cols = pd.read_excel('sales_data.xlsx', usecols=lambda col: 'Amount' in col)
    print(df_filtered_cols.head())

9. 指定数据类型 (Data Types)

Pandas 会尽力自动推断每列的数据类型(如整数、浮点数、字符串、日期等)。然而,自动推断有时可能不准确(例如,包含数字和文本的列可能被全部读作字符串,或者纯数字的列可能被误读为浮点数而不是整数)。使用 dtype 参数可以明确指定列的数据类型。

  • 为所有列指定统一数据类型:
    传递一个数据类型(如 str, float, int, object 等)可以将其应用于所有列。
    python
    # 将所有列都读作字符串
    df_all_string = pd.read_excel('my_data.xlsx', dtype=str)
    print(df_all_string.dtypes)

  • 为特定列指定数据类型:
    更常见的是使用一个字典,其中键是列名或列索引,值是要指定的数据类型。
    “`python
    # 假设文件中有 ‘ID’ (整数), ‘Amount’ (浮点数), ‘Date’ (日期)
    dtype_spec = {
    ‘ID’: int,
    ‘Amount’: float,
    ‘Date’: str # 先读成字符串,后面再解析日期
    # 也可以使用字符串形式的数据类型,如 ‘int64’, ‘float64’, ‘object’
    # ‘ID’: ‘int64’,
    # ‘Amount’: ‘float64’
    }
    df_specific_types = pd.read_excel(‘sales_data.xlsx’, dtype=dtype_spec)
    print(df_specific_types.dtypes)

    使用列索引指定

    dtype_spec_by_index = {0: int, 2: float} # 假设 ID 是第一列,Amount 是第三列

    df_specific_types_by_index = pd.read_excel(‘sales_data.xlsx’, dtype=dtype_spec_by_index)

    ``
    明确指定数据类型有助于避免类型推断错误,确保数据以正确的格式加载。特别是对于身份证号、邮政编码等应被视为文本的数字序列,指定
    dtype=’object’str` 非常重要。

10. 处理缺失值 (Missing Values)

Excel 文件中常常包含空单元格或特定的标记来表示缺失数据。Pandas 默认会将这些空单元格读取为 NaN (Not a Number),这是 Pandas 表示缺失值的标准方式。read_excel() 提供了 na_values 参数来识别除了空单元格之外的其他表示缺失值的值。

  • 默认行为:
    空单元格被读作 NaN
    python
    df = pd.read_excel('data_with_blanks.xlsx')
    print(df.isnull().sum()) # 查看每列有多少缺失值

  • 指定额外的值作为缺失值:
    使用一个列表或集合来指定哪些值应该被识别为缺失值。
    python
    # 假设 Excel 文件中用 'N/A', 'None', '-' 来表示缺失值
    missing_value_markers = ['N/A', 'None', '-']
    df_cleaned_na = pd.read_excel('data_with_markers.xlsx', na_values=missing_value_markers)
    print(df_cleaned_na.isnull().sum())

  • 为不同列指定不同的缺失值标记:
    使用一个字典,其中键是列名或列索引,值是该列对应的缺失值标记列表。
    python
    # 假设 'SalesAmount' 列用 'NA' 表示缺失,'Quantity' 列用 '-999' 表示缺失
    specific_na_values = {
    'SalesAmount': ['NA'],
    'Quantity': [-999]
    }
    df_col_specific_na = pd.read_excel('data_varied_na.xlsx', na_values=specific_na_values)
    print(df_col_specific_na.isnull().sum())

  • keep_default_na 参数:
    默认情况下 (keep_default_na=True),Pandas 会识别一些常见的缺失值字符串(如 ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘n/a’, ‘nan’, ‘null’, ”)。如果你设置了 na_values 参数,并且想保留这些默认的缺失值识别,就保持 keep_default_na=True。如果你只想识别 na_values 中指定的值,可以将 keep_default_na 设置为 False

11. 处理日期和时间

Excel 在处理日期和时间方面有时会比较复杂,因为它可以存储为数字(序列号)或文本。Pandas 的 read_excel() 函数提供了 parse_dates 参数来帮助正确解析日期列。

  • 自动尝试解析日期列:
    设置 parse_dates=True 将尝试将看起来像日期的列解析为 Pandas 的日期时间对象。
    python
    # Pandas 会尝试识别哪些列可能是日期
    df_parsed_dates = pd.read_excel('data_with_dates.xlsx', parse_dates=True)
    print(df_parsed_dates.info()) # 查看列的数据类型,日期列应该是 datetime64[ns]

    这种自动识别并不总是可靠,尤其当日期格式不标准时。

  • 指定要解析的日期列:
    可以传递一个列名列表或列索引列表来明确指定哪些列应该被解析为日期。
    “`python
    # 假设 ‘OrderDate’ 和 ‘ShipDate’ 列是日期列
    df_specific_dates = pd.read_excel(‘sales_data.xlsx’, parse_dates=[‘OrderDate’, ‘ShipDate’])
    print(df_specific_dates.info())

    使用列索引

    df_specific_dates_idx = pd.read_excel(‘sales_data.xlsx’, parse_dates=[2, 5]) # 假设它们是第3和第6列

    “`

  • 将多列合并解析为日期:
    可以传递一个嵌套列表,其中每个内层列表包含构成一个日期/时间的列名或索引。例如,Excel 中有 ‘Year’, ‘Month’, ‘Day’ 三列,你想将它们合并解析为一个日期列。
    python
    # 假设 Excel 有 'Year', 'Month', 'Day' 三列
    df_combined_date = pd.read_excel('data_ymd.xlsx', parse_dates=[['Year', 'Month', 'Day']])
    print(df_combined_date.info())
    print(df_combined_date.head()) # 会生成一个新的列,通常命名为 'Year_Month_Day'

  • 结合使用 dtypeparse_dates:
    有时,如果日期格式非常不规范,Pandas 自动解析可能会失败。一个常见的做法是先将该列作为字符串读取 (dtype={'DateColumn': str}),然后再使用 Pandas 的 pd.to_datetime() 函数进行手动解析,这提供了更多的控制(例如,指定日期格式 format='%Y%m%d')。

  • date_parser 参数:
    对于更复杂的日期格式或需要自定义解析逻辑,可以使用 date_parser 参数提供一个函数。这个函数将接收日期字符串并返回一个日期时间对象。不过,通常情况下,先读作字符串再用 pd.to_datetime() 更灵活方便。

12. 使用 converters 参数进行自定义转换

converters 参数允许你在读取数据时对特定列的值应用一个函数进行转换。这对于处理一些特殊格式的数据非常有用,例如:

  • 将数字格式化为文本(如电话号码,前面可能有 0)。
  • 清理单元格中的额外空格或非打印字符。
  • 根据条件转换值。

converters 参数接受一个字典,键是列名或列索引,值是应用于该列每个单元格值的函数。

“`python

假设 ‘PhoneNumber’ 列有时前面有 0,Excel 可能将其读作数字并丢失前导零

假设 ‘Category’ 列包含一些不必要的空格

converter_funcs = {
‘PhoneNumber’: lambda x: str(x).zfill(10), # 强制转为字符串并填充到 10 位
‘Category’: lambda x: str(x).strip() # 移除字符串两端的空格
}
df_converted = pd.read_excel(‘data_with_formatting.xlsx’, converters=converter_funcs)
print(df_converted[[‘PhoneNumber’, ‘Category’]].head())
“`
注意,转换函数接收的是单元格的原始值(通常是字符串或数字),返回的是转换后的值。

13. 处理数字格式和分隔符

在不同的区域设置中,数字的小数点和千位分隔符可能不同(例如,欧洲使用逗号作为小数点,点作为千位分隔符)。read_excel() 提供了 decimalthousands 参数来正确解析这些数字。

  • decimal: 指定小数点使用的字符,默认为 .
  • thousands: 指定千位分隔符使用的字符,默认为 None

“`python

假设 Excel 文件中的数字格式是 ‘1.234,56’ (点是千位分隔符,逗号是小数点)

df_european_numbers = pd.read_excel(‘european_sales.xlsx’, thousands=’.’, decimal=’,’)
print(df_european_numbers.head())
print(df_european_numbers.dtypes) # 确保数字列被正确读作 float
“`

14. 处理布尔值

Excel 文件中可能使用特定的文本来表示布尔值(如 ‘Yes’/’No’, ‘True’/’False’, ‘1’/’0’)。read_excel() 提供了 true_valuesfalse_values 参数来指定哪些字符串应该被解析为 TrueFalse

  • true_values: 一个列表,指定哪些字符串应该被视为 True
  • false_values: 一个列表,指定哪些字符串应该被视为 False

“`python

假设 ‘IsActive’ 列使用 ‘Active’ 和 ‘Inactive’ 来表示布尔状态

df_boolean_col = pd.read_excel(‘user_status.xlsx’,
true_values=[‘Active’, ‘YES’],
false_values=[‘Inactive’, ‘NO’])
print(df_boolean_col.head())
print(df_boolean_col.dtypes) # 检查 ‘IsActive’ 列是否被读作 bool
“`

15. 性能考虑和读取大型文件

读取非常大的 Excel 文件可能会消耗大量内存并花费较长时间。以下是一些优化策略:

  • 只读取必要的列: 使用 usecols 参数只加载你需要的列。
  • 只读取必要的行: 使用 nrows 参数在开发或初步探索时只读取文件开头的小部分数据。
  • 指定数据类型: 使用 dtype 参数为列指定最合适的数据类型。例如,如果一列只包含 0-1000 的整数,使用 int16 可能比默认的 int64 更节省内存。避免将可以表示为数字或日期的列读作 object (字符串),因为字符串通常需要更多内存。
  • 考虑文件格式: 对于非常大的数据集,CSV 文件通常比 Excel 文件更适合用 Pandas 读取,因为它们是纯文本格式,处理起来更直接,并且 pd.read_csv 支持 chunksize 参数分块读取。如果可能,将大型 Excel 文件转换为 CSV 再处理。
  • 使用合适的 engine: 虽然 openpyxl 是推荐的现代 .xlsx 读取引擎,但如果你遇到兼容性或性能问题,可以尝试切换引擎(例如,对于老旧的 .xls 文件强制使用 xlrd)。

16. 错误处理和常见问题

在使用 read_excel() 时,可能会遇到一些错误:

  • FileNotFoundError: 文件路径不正确。请检查文件是否存在以及路径是否正确(包括文件扩展名)。
  • ModuleNotFoundError: 缺少必要的引擎库 (openpyxl, xlrd, odfpy, pyxlsb)。请确保已经安装了所有需要的库。
  • xlrd.biffh.XLRDError: Excel xlsx file; not supported: 你正在尝试使用老版本的 xlrd 读取 .xlsx 文件。请确保安装了 openpyxl 并允许 Pandas 自动选择引擎(或显式指定 engine='openpyxl')。
  • ValueError: Plan name ... does not exist: sheet_name 指定的工作表名称或索引不存在。请检查工作表名称是否拼写正确或索引是否超出范围。
  • XLRDError: Can't find workbook in OLE2 compound document: 文件可能不是有效的 .xls 格式,或者文件已损坏。
  • 数据类型错误: 列的数据没有被正确读取为期望的类型。检查原始 Excel 数据是否一致,或者使用 dtype, converters, parse_dates 参数进行手动控制。
  • 列名或索引问题: headerindex_col 参数设置不正确,导致列名或索引不是你预期的样子。

当遇到问题时,仔细阅读错误信息通常能提供解决问题的线索。查看 Pandas 官方文档 (pd.read_excel?help(pd.read_excel)) 可以获取更详细的参数说明。

17. 综合示例

让我们看一个更复杂的例子,结合使用多个参数来读取一个模拟的销售报告文件。

假设 complex_sales_report.xlsx 文件有以下特点:

  • 数据在名为 “Q3 Sales” 的工作表中。
  • 文件开头有 3 行报告标题和说明。
  • 列名在第 4 行(Excel 中的第 4 行)。
  • 第一列是订单号,应该作为索引。
  • 只需要读取 ‘OrderDate’, ‘Region’, ‘Product’, ‘Amount’ 这几列。
  • ‘Amount’ 列可能包含逗号作为千位分隔符。
  • ‘Region’ 列可能包含 ‘N/A’ 或空单元格表示缺失。

“`python
import pandas as pd

try:
# 指定文件路径
file_path = ‘complex_sales_report.xlsx’

# 使用 read_excel 函数读取数据,并应用多个参数
df_sales = pd.read_excel(
    file_path,
    sheet_name='Q3 Sales',   # 指定工作表名称
    skiprows=3,              # 跳过开头的 3 行
    header=0,                # 在跳过 3 行后,将下一行(原文件第 4 行)作为列名 (因为skiprows=3,所以这里header=0是相对于跳过后的行的索引)
    index_col='Order ID',    # 将名为 'Order ID' 的列设为索引
    usecols=['Order ID', 'OrderDate', 'Region', 'Product', 'Amount'], # 只读取这几列
    thousands=',',           # 指定千位分隔符为逗号
    na_values=['N/A', ''],   # 指定 'N/A' 和空字符串为缺失值
    parse_dates=['OrderDate'] # 将 'OrderDate' 列解析为日期
)

# 打印读取结果的一些信息
print("成功读取文件,DataFrame 信息:")
df_sales.info()

print("\n前 5 行数据:")
print(df_sales.head())

print("\n缺失值统计:")
print(df_sales.isnull().sum())

except FileNotFoundError:
print(f”错误: 文件 ‘{file_path}’ 未找到。请检查文件路径是否正确。”)
except ValueError as ve:
print(f”错误: 读取文件时发生值错误 – {ve}”)
print(“请检查 sheet_name, header, usecols, index_col 等参数是否与文件内容匹配。”)
except Exception as e:
print(f”读取文件时发生未知错误: {e}”)

``
为了运行这个示例,你需要创建一个名为
complex_sales_report.xlsx` 的 Excel 文件,并在其中创建一个名为 “Q3 Sales” 的工作表,包含示例中提到的列和数据结构。

这个例子展示了如何结合使用 sheet_name, skiprows, header, index_col, usecols, thousands, na_values, parse_dates 等参数来精确地读取复杂格式的 Excel 数据。

18. 总结

通过本文的详细介绍,你应该对如何使用 Pandas 的 read_excel() 函数读取 Excel 文件有了全面的理解。我们学习了:

  • 安装必要的库。
  • 使用 sheet_name 处理单个、多个或所有工作表。
  • 使用 header 处理不同位置的列名或无列名的情况。
  • 使用 index_col 设置单列或多列索引。
  • 使用 skiprowsnrows 控制读取的行范围。
  • 使用 usecols 选择特定的列。
  • 使用 dtype 强制指定列的数据类型。
  • 使用 na_values 识别自定义的缺失值标记。
  • 使用 parse_dates 处理日期和时间列。
  • 使用 converters 进行自定义的数据转换。
  • 使用 decimalthousands 处理不同的数字格式。
  • 使用 true_valuesfalse_values 解析布尔值。
  • 以及如何考虑性能和进行基本的错误处理。

掌握 read_excel() 函数的各种参数,能够让你灵活高效地处理各种复杂结构的 Excel 文件,为后续的数据清洗、分析和建模打下坚实的基础。

在实际工作中,遇到新的 Excel 文件时,最好的方法是先手动打开它,观察其结构(工作表名称、标题行、数据起始行、列名位置、是否存在特殊标记、数据类型等),然后根据观察结果选择合适的 read_excel() 参数。

通过不断实践和尝试,你将能够熟练运用 Pandas 读取各种 Excel 数据,开启你的数据探索之旅!


发表评论

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

滚动至顶部