Pandas read_excel
函数:完整操作指南
导言
在数据分析、数据科学以及日常的数据处理工作中,Excel 文件(.xls
或 .xlsx
)无疑是最常见的数据源之一。无论是业务报告、调查结果还是小型数据集,Excel 文件都扮演着重要的角色。作为 Python 中最强大的数据处理库之一,Pandas 提供了高效且灵活的方式来读取、处理和分析各种格式的数据,其中就包括了对 Excel 文件的原生支持。
Pandas 中用于读取 Excel 文件的核心函数是 pandas.read_excel()
。这个函数功能强大,参数众多,可以应对从简单的单表读取到复杂的、包含多表、特定区域、特殊数据类型等多种场景。掌握 read_excel()
的各种用法是使用 Pandas 进行数据清洗和预处理的基础。
本文将带你深入了解 read_excel()
函数的各个方面,从基础用法到高级参数,提供详细的解释和丰富的代码示例,帮助你全面掌握如何利用 Pandas 读取 Excel 文件。
1. 前置准备:安装必要的库
在使用 read_excel()
之前,你需要确保已经安装了 Pandas 库。此外,由于 Pandas 自身并不直接处理 Excel 文件的二进制格式,它依赖于第三方库来完成实际的解析工作。最常用的两个库是:
openpyxl
: 用于读取.xlsx
格式的文件(Excel 2007+)。这是 Pandas 读取.xlsx
的默认引擎。xlrd
: 用于读取较旧的.xls
格式的文件(Excel 2003 及更早版本)。注意,xlrd
的新版本(>=2.0.1)不再支持.xlsx
文件,如果需要读取.xls
和.xlsx
文件,建议安装较新版本的 Pandas 和openpyxl
,并确保安装的是支持.xls
的xlrd
版本 (例如xlrd<2.0.0
)。不过通常情况下,安装openpyxl
已经能满足大部分.xlsx
文件的读取需求。
你可以使用 pip 来安装这些库:
bash
pip install pandas openpyxl xlrd
安装完成后,就可以开始使用 read_excel()
函数了。
2. 基本用法:读取默认工作表
最简单的情况下,你只需要提供 Excel 文件的路径,read_excel()
函数就会尝试读取文件中的第一个工作表(通常是第一个可见的工作表),并将其转换为一个 Pandas DataFrame。
假设你有一个名为 sample.xlsx
的 Excel 文件,其中包含以下数据:
ID | Name | City | Date | Value |
---|---|---|---|---|
1 | Alice | New York | 2023/01/15 | 100 |
2 | Bob | London | 2023/01/16 | 150 |
3 | Charlie | Tokyo | 2023/01/17 | 200 |
文件路径可以是相对路径或绝对路径。
“`python
import pandas as pd
假设 sample.xlsx 文件与脚本在同一目录下
file_path = ‘sample.xlsx’
try:
df = pd.read_excel(file_path)
print(“成功读取 Excel 文件:”)
print(df)
except FileNotFoundError:
print(f”错误:文件 ‘{file_path}’ 未找到。请检查文件路径。”)
except Exception as e:
print(f”读取文件时发生错误:{e}”)
“`
解释:
pd.read_excel(file_path)
是最基本的调用方式。- 函数返回的是一个 Pandas DataFrame 对象
df
。 - 默认情况下,
read_excel
会将 Excel 文件的第一行识别为列名(表头)。 - 它会尝试根据单元格的内容自动推断数据的类型(整数、浮点数、字符串、日期等)。
运行上述代码,如果文件存在且格式正确,你将看到一个与 Excel 内容对应的 DataFrame 打印输出。
3. 处理多个工作表(Sheets)
一个 Excel 文件通常包含一个或多个工作表。read_excel()
提供了 sheet_name
参数来控制读取哪个工作表。
sheet_name
参数非常灵活,它可以接受以下几种值:
- 整数(int): 工作表的索引(从 0 开始)。
sheet_name=0
表示第一个工作表,sheet_name=1
表示第二个工作表,以此类推。 - 字符串(str): 工作表的名称。例如
sheet_name='Sheet1'
。 - 列表(list): 包含工作表索引或名称的列表。例如
sheet_name=[0, 'Sheet2', 3]
。这将读取指定的多个工作表,并返回一个字典,键是工作表名称,值是对应的 DataFrame。 - None: 读取文件中的所有工作表。同样返回一个字典,键是工作表名称,值是对应的 DataFrame。
假设 sample.xlsx
文件中有三个工作表:’Sheet1′ (如上例数据), ‘Sheet2’ (包含其他数据), 和 ‘Sheet3’ (空表或汇总信息)。
3.1 读取指定名称的工作表
“`python
读取名为 ‘Sheet2’ 的工作表
df_sheet2 = pd.read_excel(file_path, sheet_name=’Sheet2′)
print(“\n读取工作表 ‘Sheet2’:”)
print(df_sheet2.head()) # 只打印前几行
“`
3.2 读取指定索引的工作表
“`python
读取第二个工作表 (索引为 1)
df_second_sheet = pd.read_excel(file_path, sheet_name=1)
print(“\n读取第二个工作表 (索引 1):”)
print(df_second_sheet.head())
“`
3.3 读取多个工作表
“`python
读取 ‘Sheet1’ 和 ‘Sheet3’
注意:即使是索引,返回字典的键也是工作表名称
dict_of_dfs = pd.read_excel(file_path, sheet_name=[‘Sheet1’, ‘Sheet3’])
print(“\n读取多个工作表 (‘Sheet1’, ‘Sheet3’):”)
dict_of_dfs 是一个字典,键是工作表名称
print(“读取到的工作表名称:”, list(dict_of_dfs.keys()))
访问特定的 DataFrame
df_from_list_sheet1 = dict_of_dfs[‘Sheet1’]
print(“\n访问字典中的 ‘Sheet1’:”)
print(df_from_list_sheet1.head())
“`
3.4 读取所有工作表
“`python
读取文件中的所有工作表
all_sheets_dict = pd.read_excel(file_path, sheet_name=None)
print(“\n读取所有工作表:”)
print(“读取到的所有工作表名称:”, list(all_sheets_dict.keys()))
遍历并打印每个工作表的前几行
for sheet_name, df_sheet in all_sheets_dict.items():
print(f”\n— 工作表 ‘{sheet_name}’ —“)
print(df_sheet.head())
“`
注意: 当 sheet_name
是列表或 None
时,返回的是一个字典。字典的键是工作表的名称(字符串),值是对应工作表的 DataFrame。
4. 控制读取行和列
在很多情况下,你不需要读取整个工作表,或者需要跳过一些 introductory text 或 summary rows。read_excel()
提供了多个参数来精细控制读取的范围。
header
: 指定哪一行作为列头。默认为 0(第一行)。可以是一个整数(指定某一行)或 None(表示没有列头)。skiprows
: 跳过文件开头的指定行数。可以是一个整数,一个行号列表,或者一个函数。nrows
: 指定要读取的数据行数(从列头或skiprows
后的第一行数据开始计算)。usecols
: 指定要读取的列。非常灵活,可以接受多种格式。skipfooter
: 跳过文件末尾的指定行数。range
: 使用 Excel 的 A1 风格范围来指定读取区域 (需要openpyxl
引擎且 Pandas 版本支持)。
假设你的 Excel 文件是这样的:
“`excel
Analysis Report
Generated on 2023-10-26
Data Table:
ID Name City Date Value
1 Alice New York 2023/01/15 100
2 Bob London 2023/01/16 150
3 Charlie Tokyo 2023/01/17 200
Total rows: 3
“`
4.1 指定列头 (header
)
默认 header=0
。如果列头在第四行(索引为 3),你需要指定 header=3
。
“`python
假设列头在第4行 (索引 3)
df_with_header = pd.read_excel(file_path, header=3)
print(“\n指定列头为第4行:”)
print(df_with_header)
“`
如果文件没有列头,或者你想自己指定列名,可以设置 header=None
。此时 Pandas 会自动生成数字列名 (0, 1, 2, …)。
“`python
假设文件没有列头
如果指定 header=None, 可以同时使用 names 参数提供列名
df_no_header = pd.read_excel(file_path, header=None)
print(“\n文件无列头:”)
print(df_no_header)
如果文件无列头且想指定列名
column_names = [‘Customer_ID’, ‘Customer_Name’, ‘Location’, ‘Order_Date’, ‘Amount’]
df_manual_names = pd.read_excel(file_path, header=None, names=column_names)
print(“\n文件无列头,手动指定列名:”)
print(df_manual_names)
“`
4.2 跳过行 (skiprows
, skipfooter
)
skiprows
可以跳过开头的行,常用于跳过文件前的描述信息。
skipfooter
可以跳过末尾的行,常用于跳过汇总行。
“`python
跳过开头的 3 行描述信息
注意:如果同时使用 header,skiprows 会在 header 之前 生效
例如,如果列头在第4行 (索引 3),且想跳过前3行描述,只需指定 header=3 即可
但如果列头在第4行,且前3行是无关信息,你也可以先 skiprows=3 再 header=0 (相对于跳过后的数据)
更常见的是,如果知道列头位置,直接用 header 即可。
skiprows 更常用于跳过非结构化文本或在特定情况下配合 header 使用
假设文件头有 3 行描述,且第 4 行是列头
df_skip_intro = pd.read_excel(file_path, skiprows=3, header=0)
print(“\n跳过开头3行:”)
print(df_skip_intro) # 注意:这里的 header=0 是相对于跳过3行后的数据的第一行
或者更简洁地直接指定 header 的位置 (推荐)
df_correct_header = pd.read_excel(file_path, header=3) # 索引从0开始,第4行是索引3
print(“\n直接指定列头位置 (第4行,索引3):”)
print(df_correct_header)
假设文件末尾有 1 行汇总信息
df_skip_footer = pd.read_excel(file_path, skipfooter=1)
print(“\n跳过末尾1行:”)
print(df_skip_footer)
结合使用
df_clean = pd.read_excel(file_path, header=3, skipfooter=1)
print(“\n跳过开头3行和末尾1行,指定第4行为列头:”)
print(df_clean)
skiprows 也可以是列表,指定要跳过的具体行号 (从 0 开始计数)
例如,跳过第 1, 2, 5 行
df_skip_specific = pd.read_excel(file_path, skiprows=[0, 1, 4])
print(“\n跳过指定行 (0, 1, 4):”)
print(df_skip_specific) # 注意这会影响后续行索引和 header 的解释
“`
4.3 读取指定行数 (nrows
)
nrows
用于限制读取的数据行数。这在你只需要查看文件开头部分或处理非常大的文件时非常有用。
“`python
只读取前 2 行数据 (不包括列头)
df_first_2_rows = pd.read_excel(file_path, nrows=2)
print(“\n只读取前 2 行数据:”)
print(df_first_2_rows)
“`
4.4 读取指定列 (usecols
)
usecols
是一个功能非常强大的参数,可以精确控制读取哪些列。它可以接受多种格式:
- None: 读取所有列 (默认)。
- 整数列表: 列的索引列表 (从 0 开始)。例如
[0, 2, 4]
读取第一、第三、第五列。 - 字符串列表: 列的名称列表。例如
['Name', 'Value']
读取 ‘Name’ 和 ‘Value’ 列。 - 字符串: Excel 列的字母范围或逗号分隔的字母。例如
'A:C'
读取 A, B, C 列;'A,C,E'
读取 A, C, E 列。 - 可调用对象 (callable): 一个函数,它接收列名(字符串)列表作为输入,返回一个布尔值数组或布尔 Series,指示哪些列需要保留。
“`python
假设文件内容如前所示 (ID, Name, City, Date, Value)
使用列索引读取 Name 和 Value 列 (索引 1 和 4)
df_cols_by_index = pd.read_excel(file_path, usecols=[1, 4])
print(“\n使用列索引读取 Name 和 Value:”)
print(df_cols_by_index)
使用列名称读取 Name 和 Value 列
df_cols_by_name = pd.read_excel(file_path, usecols=[‘Name’, ‘Value’])
print(“\n使用列名称读取 Name 和 Value:”)
print(df_cols_by_name)
使用 Excel 列字母范围读取前三列 (A, B, C)
df_cols_by_letter_range = pd.read_excel(file_path, usecols=’A:C’)
print(“\n使用 Excel 字母范围读取前三列 (A:C):”)
print(df_cols_by_letter_range)
使用 Excel 列字母读取指定的列 (A, C, E)
df_cols_by_letters = pd.read_excel(file_path, usecols=’A,C,E’)
print(“\n使用 Excel 字母读取指定列 (A,C,E):”)
print(df_cols_by_letters)
使用可调用对象:读取所有名称包含 ‘a’ 或 ‘A’ 的列
注意:这里的 lambda 函数接收的是列名 (字符串)
df_cols_by_callable = pd.read_excel(file_path, usecols=lambda col: ‘a’ in col.lower())
print(“\n使用可调用对象读取列名包含 ‘a’ 的列:”)
print(df_cols_by_callable)
“`
重要提示: 当使用 usecols
参数时,Pandas 只会读取指定的列,这对于处理包含大量无关列的大文件时可以显著提高性能和减少内存使用。
4.5 使用 A1 风格范围 (range
)
这个参数是 read_excel
较新的功能,它允许你使用标准的 Excel A1 风格的单元格范围表示法来指定要读取的区域。这非常直观,特别是当你只需要工作表中的一个特定矩形区域时。
注意: range
参数需要 Pandas 版本支持,并且通常依赖 openpyxl
引擎。如果同时使用 range
和 header
参数,header
是相对于 range
指定区域的第一行计算的。如果同时使用 range
和 usecols
,usecols
必须是指定范围内的列索引或名称。不建议同时使用 range
和 skiprows
, nrows
, skipfooter
,因为功能有重叠且可能引起混淆。
“`python
假设文件数据在区域 B3:D6 (包含 B3, C3, D3 行作为列头)
B3:D6 对应 Excel 中的区域
创建一个模拟文件来更好地演示 range 参数
例如,区域 B3:D6 包含 Name, City, Date 列及其对应的 3 行数据
excel_data = {
‘Sheet1’: [
[None, None, None, None, None],
[None, None, None, None, None],
[None, ‘Name’, ‘City’, ‘Date’, None],
[None, ‘Alice’, ‘New York’, ‘2023/01/15’, None],
[None, ‘Bob’, ‘London’, ‘2023/01/16’, None],
[None, ‘Charlie’, ‘Tokyo’, ‘2023/01/17’, None],
[None, None, None, None, None],
]
}
将模拟数据写入 Excel 文件 (需要 openpyxl)
from io import BytesIO
output = BytesIO()
with pd.ExcelWriter(output, engine=’openpyxl’) as writer:
for sheet_name, data in excel_data.items():
# 创建一个临时的DataFrame来写入,以便写入到指定单元格
temp_df = pd.DataFrame(data)
temp_df.to_excel(writer, sheet_name=sheet_name, index=False, header=False) # 写入时不需要 header 和 index
output.seek(0) # 重置文件指针
使用 range 参数读取 B3:D6 区域,并将 B3:D3 作为列头
header=0 表示在指定区域 (B3:D6) 内,将第一行 (B3:D3) 作为列头
df_range = pd.read_excel(output, sheet_name=’Sheet1′, range=’B3:D6′, header=0)
print(“\n使用 range 参数读取 B3:D6 区域:”)
print(df_range)
另一个例子:读取 B4:C6 区域,无列头
output.seek(0) # 重置文件指针
df_range_no_header = pd.read_excel(output, sheet_name=’Sheet1′, range=’B4:C6′, header=None)
print(“\n使用 range 参数读取 B4:C6 区域 (无列头):”)
print(df_range_no_header)
“`
range
参数非常适合处理那些数据表不是从 A1 单元格开始的复杂 Excel 文件。
5. 处理数据类型和缺失值
Excel 文件中的数据类型可能不像数据库那样严格,而且经常包含空白单元格或特定的标记来表示缺失值。read_excel()
提供了参数来帮助你更好地控制数据类型和处理缺失值。
dtype
: 指定列的数据类型。可以是一个数据类型(应用于所有列)或一个字典(将列名映射到数据类型)。na_values
: 一个值或一个列表,这些值在 Excel 中将被识别为 NaN(Not a Number)或 NaT(Not a Time,对于日期时间类型)。keep_default_na
: 是否包括 Pandas 默认的缺失值标记(如 ”, ‘#N/A’, ‘NULL’ 等)。默认为 True。如果设置为 False,则只有na_values
中指定的值会被视为缺失值。parse_dates
: 指定哪些列应该被解析为日期时间类型。
5.1 指定列数据类型 (dtype
)
Pandas 会尝试自动推断数据类型,但这有时可能不准确(例如,包含数字和非数字混合的列可能会被读作 object
类型)。使用 dtype
可以明确指定每列的类型。
“`python
假设 Value 列应该总是浮点数,ID 列应该总是整数
df_with_dtype = pd.read_excel(file_path, dtype={‘ID’: int, ‘Value’: float})
print(“\n指定 ID 为 int, Value 为 float:”)
print(df_with_dtype.dtypes)
print(df_with_dtype)
指定所有列为字符串类型 (避免类型推断问题)
df_all_str = pd.read_excel(file_path, dtype=str)
print(“\n所有列读取为字符串:”)
print(df_all_str.dtypes)
print(df_all_str)
“`
5.2 处理缺失值 (na_values
, keep_default_na
)
na_values
可以将 Excel 中的特定字符串转换为 Pandas 的缺失值表示 (NaN
或 NaT
)。
“`python
假设 Excel 中用 ‘N/A’ 或 ‘-‘ 表示缺失值
df_na_values = pd.read_excel(file_path, na_values=[‘N/A’, ‘-‘])
print(“\n将 ‘N/A’ 和 ‘-‘ 视为缺失值:”)
print(df_na_values)
如果你只希望 ‘N/A’ 和 ‘-‘ 被视为缺失值,而不包括 Pandas 默认的
df_na_values_only = pd.read_excel(file_path, na_values=[‘N/A’, ‘-‘], keep_default_na=False)
print(“\n只将 ‘N/A’ 和 ‘-‘ 视为缺失值:”)
print(df_na_values_only)
“`
5.3 解析日期时间 (parse_dates
, date_parser
, date_infer_by_column
)
Excel 中的日期通常以数字形式存储,并应用格式化。read_excel()
可以自动识别并解析大多数常见的日期格式。但如果日期格式特殊,或者需要将多个列合并解析为日期,就需要使用 parse_dates
。
parse_dates
参数可以接受多种形式:
- 布尔值:
True
会尝试解析索引。 - 列表: 包含列名的列表,这些列将被解析为日期。
- 列表中的列表:
[['col1', 'col2']]
表示将 ‘col1’ 和 ‘col2’ 两列合并解析为一个日期时间列。 - 字典:
{new_name: ['col1', 'col2']}
表示将 ‘col1’ 和 ‘col2’ 合并解析为一个新的日期时间列,并命名为new_name
。
“`python
假设 Date 列需要被解析为日期时间
df_parse_date = pd.read_excel(file_path, parse_dates=[‘Date’])
print(“\n将 ‘Date’ 列解析为日期时间:”)
print(df_parse_date.info()) # 查看数据类型
print(df_parse_date)
假设有 ‘Year’, ‘Month’, ‘Day’ 三列需要合并解析为日期
模拟一个包含 Year, Month, Day 列的文件
excel_data_date_parts = {
‘Sheet1’: [
[‘Year’, ‘Month’, ‘Day’, ‘Value’],
[2023, 1, 15, 100],
[2023, 1, 16, 150],
[2023, 1, 17, 200],
]
}
output_date_parts = BytesIO()
with pd.ExcelWriter(output_date_parts, engine=’openpyxl’) as writer:
pd.DataFrame(excel_data_date_parts[‘Sheet1′]).to_excel(writer, sheet_name=’Sheet1’, index=False, header=False)
output_date_parts.seek(0)
使用列表中的列表合并解析
这里 header=0 是因为模拟数据第一行就是列头
df_combined_date = pd.read_excel(output_date_parts, header=0, parse_dates=[[‘Year’, ‘Month’, ‘Day’]])
print(“\n合并 ‘Year’, ‘Month’, ‘Day’ 列解析为日期时间:”)
print(df_combined_date.info())
print(df_combined_date) # 注意生成的列名是合并列名的组合
使用字典合并解析并指定新列名
output_date_parts.seek(0) # 重置文件指针
df_combined_date_named = pd.read_excel(output_date_parts, header=0, parse_dates={‘Order_Date’: [‘Year’, ‘Month’, ‘Day’]})
print(“\n合并 ‘Year’, ‘Month’, ‘Day’ 列解析为日期时间,指定新列名 ‘Order_Date’:”)
print(df_combined_date_named.info())
print(df_combined_date_named)
“`
如果你的日期格式非常规,或者 Pandas 无法自动识别,你可以使用 date_parser
参数提供一个自定义的解析函数。这个函数需要接收一个字符串作为输入(表示日期),返回一个 datetime
对象。通常建议使用 pandas.to_datetime
或 dateutil.parser.parse
作为解析函数,或者使用 dayfirst
参数来指示日/月/年顺序。
date_infer_by_column=True
参数(默认为 False)可以尝试通过检查每一列的数值来推断日期格式,这在处理混合格式或不确定格式的日期列时可能有用,但有时会降低性能。
5.4 其他类型处理参数
converters
: 一个字典,键是列名,值是用于处理该列中每个单元格值的函数。可以在读取时对数据进行自定义转换。true_values
,false_values
: 字符串列表,分别用于将这些字符串识别为布尔值 True 和 False。decimal
: 指定用于小数点分隔符的字符(默认为 ‘.’)。如果你的 Excel 文件使用 ‘,’ 作为小数点,需要设置decimal=','
。
“`python
假设 ‘Value’ 列存储为字符串,且包含货币符号 ‘$’,需要转换为浮点数
假设 ‘Is_Active’ 列使用 ‘Yes’/’No’ 表示布尔值
假设某个数值列使用 ‘,’ 作为小数点
模拟数据
excel_data_conversion = {
‘Sheet1’: [
[‘Item’, ‘Price’, ‘Is_Active’, ‘Quantity’],
[‘Apple’, ‘$1.20’, ‘Yes’, ‘50,5’], # 注意 Quantity 列使用逗号
[‘Banana’, ‘$0.50’, ‘No’, ‘200’],
[‘Orange’, ‘$0.99’, ‘Yes’, ‘150’],
]
}
output_conversion = BytesIO()
with pd.ExcelWriter(output_conversion, engine=’openpyxl’) as writer:
pd.DataFrame(excel_data_conversion[‘Sheet1′]).to_excel(writer, sheet_name=’Sheet1’, index=False, header=False)
output_conversion.seek(0)
使用 converters, true_values, false_values, decimal
df_converted = pd.read_excel(
output_conversion,
header=0,
converters={
‘Price’: lambda x: float(str(x).replace(‘$’, ”).strip()) # 移除 ‘$’ 并转浮点
},
true_values=[‘Yes’],
false_values=[‘No’],
decimal=’,’ # 指定 Quantity 列使用 ‘,’ 作为小数点
)
print(“\n使用 converters, true_values, false_values, decimal:”)
print(df_converted.info())
print(df_converted)
“`
6. 设置索引列 (index_col
)
默认情况下,Pandas 会为 DataFrame 分配一个从 0 开始的整数索引。你可以使用 index_col
参数将 Excel 文件中的某一列或多列指定为 DataFrame 的索引。
index_col
可以接受以下值:
- None: 不使用任何列作为索引,使用默认整数索引 (默认)。
- 整数或字符串: 指定作为索引的单列的索引或名称。
- 整数列表或字符串列表: 指定作为索引的多列的索引或名称 (创建 MultiIndex)。
- 布尔值 False: 明确表示不使用任何列作为索引。
“`python
假设 ID 列应该作为 DataFrame 的索引
df_with_index = pd.read_excel(file_path, index_col=’ID’)
print(“\n使用 ‘ID’ 列作为索引:”)
print(df_with_index)
使用第一列 (索引 0) 作为索引
df_with_index_by_pos = pd.read_excel(file_path, index_col=0)
print(“\n使用第一列作为索引:”)
print(df_with_index_by_pos)
假设有两列 (例如 ‘Year’, ‘Month’) 需要作为复合索引
模拟数据
excel_data_multiindex = {
‘Sheet1’: [
[‘Year’, ‘Month’, ‘Sales’],
[2023, 1, 1000],
[2023, 2, 1200],
[2024, 1, 1500],
]
}
output_multiindex = BytesIO()
with pd.ExcelWriter(output_multiindex, engine=’openpyxl’) as writer:
pd.DataFrame(excel_data_multiindex[‘Sheet1′]).to_excel(writer, sheet_name=’Sheet1’, index=False, header=False)
output_multiindex.seek(0)
df_multiindex = pd.read_excel(output_multiindex, header=0, index_col=[‘Year’, ‘Month’])
print(“\n使用 ‘Year’ 和 ‘Month’ 作为复合索引:”)
print(df_multiindex)
“`
7. 其他常用参数
squeeze
: 如果读取结果只有一列,设置为True
可以返回一个 Series 而不是 DataFrame。在较新版本的 Pandas 中,此参数已被弃用,推荐使用.squeeze("columns")
方法在读取 后 进行转换。engine
: 指定用于读取 Excel 文件的引擎。默认为 None,Pandas 会根据文件扩展名自动选择 (‘openpyxl’ for .xlsx, ‘xlrd’ for .xls)。你可以强制指定引擎,例如engine='openpyxl'
。comment
: 指定一个字符,该字符在行首出现时表示该行是注释,应该被跳过。verbose
: 显示更多调试信息。
“`python
# 示例:使用 squeeze (注意:在较新版本中不推荐)
# 假设 sample.xlsx 只有 Name 一列
# 需要一个只有一列的模拟文件
excel_data_single_col = {
‘Sheet1’: [
[‘Name’],
[‘Alice’],
[‘Bob’],
]
}
output_single_col = BytesIO()
with pd.ExcelWriter(output_single_col, engine=’openpyxl’) as writer:
pd.DataFrame(excel_data_single_col[‘Sheet1′]).to_excel(writer, sheet_name=’Sheet1’, index=False, header=False)
output_single_col.seek(0)
# df_series = pd.read_excel(output_single_col, header=0, squeeze=True) # squeeze 参数已弃用
# print(“\n使用 squeeze (弃用,返回 Series):”)
# print(type(df_series))
# print(df_series)
# 推荐的做法是在读取后使用 .squeeze()
output_single_col.seek(0)
df_single_col = pd.read_excel(output_single_col, header=0)
series_from_df = df_single_col.squeeze(“columns”)
print(“\n读取单列 DataFrame 后使用 .squeeze():”)
print(type(series_from_df))
print(series_from_df)
示例:强制使用 openpyxl 引擎
df_force_engine = pd.read_excel(file_path, engine=’openpyxl’)
print(“\n强制使用 openpyxl 引擎读取:”)
print(df_force_engine.head())
示例:使用 comment 参数 (假设以 ‘#’ 开头的行是注释)
模拟数据
excel_data_comment = {
‘Sheet1’: [
[‘# This is a comment line’],
[‘ID’, ‘Name’, ‘Value’],
[1, ‘Alice’, 100],
[‘# Another comment’],
[2, ‘Bob’, 150],
]
}
output_comment = BytesIO()
with pd.ExcelWriter(output_comment, engine=’openpyxl’) as writer:
pd.DataFrame(excel_data_comment[‘Sheet1′]).to_excel(writer, sheet_name=’Sheet1’, index=False, header=False)
output_comment.seek(0)
df_with_comment = pd.read_excel(output_comment, header=1, comment=’#’) # header=1 因为第0行是注释
print(“\n使用 comment 参数忽略注释行:”)
print(df_with_comment)
“`
8. 处理大型 Excel 文件和性能考虑
读取大型 Excel 文件可能会消耗大量内存和时间。以下是一些提高效率的技巧:
- 只读取必要的列: 使用
usecols
参数只加载你需要分析的列。这是提高性能最有效的方法之一。 - 只读取必要的行: 如果只需要文件开头或特定数量的数据,使用
nrows
参数。 - 指定数据类型: 使用
dtype
参数可以避免 Pandas 在读取时进行类型推断,从而加快速度并减少内存使用(特别是对于数字列)。 - 考虑替代格式: 对于非常大的数据集,将数据保存为 Parquet、Feather 或 CSV 等格式通常比 Excel 更高效,Pandas 对这些格式的读写也更快。
9. 常见错误和故障排除
FileNotFoundError
: 文件路径不正确。检查文件是否存在以及路径是否正确。ImportError
或ModuleNotFoundError
: 缺少必要的引擎库 (openpyxl
或xlrd
)。请确保已通过pip install
安装。XLRDError: Excel xlsx file; not supported
: 你可能在使用旧版本的xlrd
或没有安装openpyxl
,而尝试读取.xlsx
文件。安装openpyxl
或更新 Pandas。如果必须读取.xls
且遇到问题,确保安装了支持.xls
的xlrd
版本(例如xlrd<2.0.0
)。- 列名或索引错误: 这通常是由于
header
,skiprows
,usecols
,index_col
参数设置不正确导致的。仔细检查 Excel 文件中实际的列头位置、需要跳过的行以及列的名称或索引。 - 数据类型错误: Pandas 可能未能正确推断数据类型。使用
dtype
参数明确指定类型。 - 日期解析错误: 日期格式不被识别。使用
parse_dates
和可能的date_parser
或dayfirst
参数。 - 内存错误 (
MemoryError
): 文件太大,超出了系统内存限制。尝试使用usecols
和nrows
只读取部分数据,或考虑分块读取( हालांकिread_excel
不直接支持分块,你可以通过多次调用并调整skiprows
和nrows
来模拟实现,但更推荐使用其他格式如 CSV 的分块读取功能)。
10. 结论
pandas.read_excel()
是一个功能强大且灵活的工具,是处理 Excel 数据的 Python 生态系统中的关键组件。通过熟练掌握 sheet_name
处理多工作表,利用 header
, skiprows
, nrows
, usecols
, range
, skipfooter
精确控制读取范围,以及使用 dtype
, na_values
, parse_dates
, converters
等参数细致处理数据类型和缺失值,你可以高效、准确地将 Excel 文件中的复杂数据导入到 Pandas DataFrame 中进行后续的分析和处理。
希望这篇详细的指南能够帮助你充分利用 read_excel()
函数,轻松应对各种 Excel 数据读取挑战!在实际应用中,结合你的具体文件结构和数据需求,灵活运用这些参数,将大大提升你的数据处理效率。