使用pandas的read_excel()函数是读取excel文件最直接且强大的方法,能将.xls或.xlsx文件转化为dataframe;2. 处理多工作表时,可通过sheet_name参数指定单个工作表(名称或索引)、设置为none读取所有工作表(返回字典),或传入列表读取多个指定工作表;3. 常见错误包括filenotfounderror(路径错误)、文件格式异常或缺失依赖库(如openpyxl/xlrd),可通过try-except捕获并提示安装对应库;4. 性能优化策略包括使用usecols仅读取必要列、skiprows和nrows跳过无关行或限制读取行数、dtype预先指定列类型以减少内存和推断时间;5. 数据清洗与分析步骤包括:用isnull().sum()检查缺失值并用dropna()或fillna()处理,用drop_duplicates()删除重复行,通过astype()、to_datetime()等转换数据类型,rename()重命名列,最后进行head()/info()/describe()概览及value_counts()、groupby()等初步分析,为后续深入分析奠定基础。

Python要读取Excel文件,最直接、最强大也几乎是行业标准的方案,就是使用
pandas库的
read_excel()函数。它能轻松处理各种Excel格式(.xls, .xlsx),并将其内容转化为Python中非常方便操作的DataFrame结构。
要读取Excel文件,
pandas库的
read_excel函数是你的首选。这个函数设计得非常直观,通常你只需要提供文件路径就能搞定大部分工作。
import pandas as pd
# 假设你的Excel文件名为 'my_data.xlsx' 并且在当前目录下
try:
df = pd.read_excel('my_data.xlsx')
print("成功读取Excel文件,前5行数据如下:")
print(df.head())
except FileNotFoundError:
print("错误:文件未找到。请检查文件路径和名称是否正确。")
except Exception as e:
print(f"读取文件时发生错误:{e}")
# 如果Excel文件在特定路径,比如桌面上的一个文件夹
# df = pd.read_excel('/Users/your_username/Desktop/data/sales_report.xlsx')
# 很多时候,Excel文件会有多个工作表(sheet),或者数据不是从第一行开始的
# 这时候就需要用到一些参数了。比如,指定读取名为 'Sheet2' 的工作表
# 或者指定数据从第3行开始(跳过前2行),并且只读取前100行
# df_specific = pd.read_excel('my_data.xlsx', sheet_name='Sheet2', skiprows=2, nrows=100)
# print("\n读取指定工作表和行数后的数据:")
# print(df_specific.head())
# 另一个常用场景是只读取某些列。比如,我只需要 '产品名称' 和 '销售额' 这两列
# df_selected_cols = pd.read_excel('my_data.xlsx', usecols=['产品名称', '销售额'])
# print("\n只读取指定列后的数据:")
# print(df_selected_cols.head())对我个人而言,
read_excel的强大之处在于它的灵活性。它不仅仅是把数据“搬”进来,还能在读取阶段就帮你做一些初步的筛选和整理,这在处理那些“不那么规范”的原始Excel文件时,简直是救命稻草。比如,我经常遇到Excel文件第一行不是表头,或者前面几行是各种报告的说明,这时候
skiprows就特别好用。
立即学习“Python免费学习笔记(深入)”;
如何处理Excel中的多个工作表?
Excel文件往往不是单枪匹马,它们通常包含多个工作表(sheet)。这种结构在数据整理时既提供了便利,也可能带来一点小麻烦,尤其是在你想一次性读取所有数据或者特定数据时。
pandas的
read_excel函数在这方面考虑得很周全,它通过
sheet_name参数提供了多种处理方式。
最直接的情况是你知道要读取哪个工作表,你可以传入工作表的名称(字符串)或者索引(整数,从0开始)。比如,我常常会把原始数据放在第一个sheet,分析结果放在第二个,这时候我就会明确指定
sheet_name=0或者
sheet_name='原始数据'。
# 读取名为 '销售数据' 的工作表
df_sales = pd.read_excel('multi_sheet_data.xlsx', sheet_name='销售数据')
print("\n--- '销售数据' 工作表内容 ---")
print(df_sales.head())
# 或者,读取第二个工作表(索引为1)
df_customers = pd.read_excel('multi_sheet_data.xlsx', sheet_name=1)
print("\n--- 第二个工作表内容 ---")
print(df_customers.head())但有时,我可能需要把所有工作表都读进来,或者只关心其中几个。这时候,
sheet_name参数的魔力就展现出来了。
如果你把
sheet_name设置为
None,
pandas会把Excel文件里的所有工作表都读进来,然后以一个字典的形式返回,字典的键就是工作表的名称,值则是对应的DataFrame。这对于需要全局概览或者后续需要合并多个工作表数据的情况非常有用。
# 读取所有工作表
all_sheets = pd.read_excel('multi_sheet_data.xlsx', sheet_name=None)
print("\n--- 所有工作表(字典形式)的键 ---")
print(all_sheets.keys())
# 访问其中一个工作表
df_products = all_sheets['产品列表']
print("\n--- '产品列表' 工作表内容 ---")
print(df_products.head())如果你只关心几个特定的工作表,可以将它们的名称组成一个列表传给
sheet_name。这样,
pandas只会读取这些指定的工作表,同样返回一个字典。这比读取所有工作表更高效,尤其是在Excel文件包含大量无关工作表时。
# 只读取 '销售数据' 和 '产品列表' 这两个工作表
selected_sheets = pd.read_excel('multi_sheet_data.xlsx', sheet_name=['销售数据', '产品列表'])
print("\n--- 选定工作表(字典形式)的键 ---")
print(selected_sheets.keys())
# 访问 '销售数据' 工作表
df_sales_selected = selected_sheets['销售数据']
print("\n--- 选定工作表中的 '销售数据' 内容 ---")
print(df_sales_selected.head())处理多工作表时,我的经验是先明确自己的需求:是只需要一个特定的,还是需要全部,抑或是部分?根据这个选择合适的
sheet_name参数,能让你的代码更简洁,效率也更高。
读取Excel时常见的错误和性能考量有哪些?
在用Python读取Excel文件的过程中,即便
pandas再强大,也难免会遇到一些“小插曲”——也就是各种错误。同时,对于大型Excel文件,性能问题也常常浮出水面。这些都是我在实际工作中反复踩过的坑,所以提前了解并有所准备非常必要。
常见错误:
-
FileNotFoundError
: 这是最常见的,通常意味着你提供的文件路径不对,或者文件名写错了。我总会先检查一遍路径是不是绝对路径,或者相对路径是否正确。try: df = pd.read_excel('non_existent_file.xlsx') except FileNotFoundError: print("错误:文件不存在或路径错误。请仔细检查文件路径和名称。") -
XLRDError
/openpyxl.utils.exceptions.InvalidFileException
: 这通常发生在Excel文件本身有问题,比如文件损坏,或者文件格式不对(你可能尝试用处理xlsx
的引擎去读xls
文件,反之亦然)。有时候,也可能是你没有安装相应的Excel引擎库。pandas
读取.xlsx
文件默认使用openpyxl
,读取.xls
文件默认使用xlrd
。如果缺失,你需要pip install openpyxl
或pip install xlrd
。# 尝试读取一个可能损坏或格式不对的文件 try: df = pd.read_excel('corrupted_file.xlsx') except Exception as e: print(f"读取文件时发生格式或引擎错误:{e}") print("提示:尝试安装 'openpyxl' (针对.xlsx) 或 'xlrd' (针对.xls)。") -
数据类型推断错误 /
ParserError
:pandas
在读取数据时会尝试推断列的数据类型。如果某一列的数据混合了数字和文本,或者日期格式不统一,就可能导致推断不准确,甚至报错。这时候,dtype
参数就派上用场了,你可以强制指定列的数据类型。# 假设 'ID' 列可能混有数字和文本,强制其为字符串 # df = pd.read_excel('mixed_data.xlsx', dtype={'ID': str, '金额': float})
性能考量:
当Excel文件变得非常大,几十兆甚至上百兆时,直接
pd.read_excel()可能会非常慢,甚至耗尽内存。这时候,我们就需要一些策略来优化读取过程。
-
只读取必要的列 (
usecols
): 这是我最常用的优化手段。如果一个Excel文件有上百列,但我只关心其中几列,那么只加载这几列能显著减少内存占用和读取时间。# 只读取 '订单号', '产品名称', '数量' 三列 df_small = pd.read_excel('large_sales_data.xlsx', usecols=['订单号', '产品名称', '数量']) print(f"只读取部分列后,DataFrame的大小:{df_small.shape}") -
跳过不必要的行 (
skiprows
,nrows
): 如果文件前面有冗余的说明行,或者你只需要文件开头或中间的一小部分数据进行测试,skiprows
和nrows
可以帮你精准定位。# 跳过前5行,只读取接下来的1000行 df_sample = pd.read_excel('large_sales_data.xlsx', skiprows=5, nrows=1000) print(f"跳过前5行并读取1000行后,DataFrame的大小:{df_sample.shape}") -
指定数据类型 (
dtype
): 提前告诉pandas
每一列应该是什么数据类型,可以避免它进行耗时的类型推断,并且能更精确地控制内存使用。比如,如果我知道某列是整数,指定int
比让pandas
推断为float
(因为有缺失值)要节省空间。# 明确指定列的数据类型,减少内存占用和推断时间 data_types = { '订单号': str, '产品名称': str, '数量': int, '销售额': float, '日期': 'datetime64[ns]' # 或者 pd.to_datetime 之后再转换 } df_typed = pd.read_excel('large_sales_data.xlsx', dtype=data_types) print("指定数据类型后读取成功。") 分块读取(对于Excel文件不直接支持,但思路可借鉴): 虽然
read_excel
不像read_csv
那样有chunksize
参数可以直接分块读取,但对于特别大的文件,你可以结合skiprows
和nrows
在一个循环中模拟分块读取,逐批处理数据,而不是一次性加载所有数据。这在内存受限的环境下非常有用。
我的经验是,在处理任何大型Excel文件之前,先用
usecols和
nrows读一小部分进来,快速看看数据的结构和类型,然后再决定如何高效地加载全部数据。这样可以节省大量试错的时间。
读取Excel后,数据清洗和初步分析的思路?
把Excel数据成功读取到
pandasDataFrame里,这只是万里长征的第一步。接下来,真正的工作才开始:数据清洗和初步分析。这部分工作至关重要,因为它直接决定了后续分析的质量和可靠性。在我看来,这就像拿到了一堆未经雕琢的宝石原石,需要细心打磨才能闪耀。
数据清洗:
清洗的核心目标是让数据变得“干净”和“可用”。
-
处理缺失值 (
NaN
): Excel数据中经常会有空单元格,在pandas
里它们会变成NaN
(Not a Number)。-
查看缺失值分布:
df.isnull().sum()
可以快速统计每列的缺失值数量。我通常会先看这个,了解哪些列问题比较大。print("\n--- 缺失值统计 ---") print(df.isnull().sum()) -
删除缺失值: 如果缺失值不多,且不影响分析,可以直接删除包含缺失值的行或列。
df.dropna()
是常用方法。# 删除所有包含缺失值的行 df_cleaned_rows = df.dropna() # 删除所有包含缺失值的列 # df_cleaned_cols = df.dropna(axis=1) print("\n--- 删除缺失值后的数据(前5行) ---") print(df_cleaned_rows.head()) -
填充缺失值: 更多时候,我们会选择填充。比如用均值、中位数、众数填充数值型数据,或者用特定字符串填充文本型数据。
df.fillna()
是你的朋友。# 用列的平均值填充 '销售额' 列的缺失值 df['销售额'] = df['销售额'].fillna(df['销售额'].mean()) # 用 '未知' 填充 '客户名称' 列的缺失值 df['客户名称'] = df['客户名称'].fillna('未知') print("\n--- 填充缺失值后的数据('销售额'和'客户名称'列) ---") print(df.head())
-
查看缺失值分布:
-
处理重复值: Excel里录入数据时,不小心重复录入的情况很常见。
-
查找重复行:
df.duplicated()
可以找出重复的行。 -
删除重复行:
df.drop_duplicates()
能帮你移除重复的行,可以选择保留第一次出现的,还是最后一次出现的。# 假设 df 已经加载 print(f"\n原始数据行数:{len(df)}") df_no_duplicates = df.drop_duplicates() print(f"删除重复行后数据行数:{len(df_no_duplicates)}")
-
查找重复行:
-
数据类型转换:
pandas
推断的数据类型不一定总是你想要的。比如,日期列可能被识别成字符串,数字可能被识别成对象(object)。df['列名'].astype(desired_type)
: 强制转换类型。pd.to_datetime()
: 专门用于日期时间转换,非常强大。pd.to_numeric()
: 强制转换为数字,并可以处理转换失败的情况。# 假设 '日期' 列被读成了字符串,转换为日期类型 df['日期'] = pd.to_datetime(df['日期'], errors='coerce') # errors='coerce' 会把无法转换的变成NaT # 确保 '数量' 列是整数 df['数量'] = pd.to_numeric(df['数量'], errors='coerce').fillna(0).astype(int) print("\n--- 转换数据类型后的信息 ---") print(df.info())
-
重命名列: Excel的列名可能包含空格、特殊字符,或者不够直观。
df.rename(columns={'旧列名': '新列名'})可以批量重命名。df = df.rename(columns={'产品名称': 'Product Name', '销售额': 'Sales Amount'}) print("\n--- 重命名列后的列名 ---") print(df.columns)
初步分析:
数据清洗完成后,就可以进行初步的探索性数据分析(EDA)了。这就像是给数据做个体检,快速了解它的全貌和潜在规律。
-
快速概览:
df.head()
/df.tail()
: 查看前几行/后几行,快速了解数据结构。df.info()
: 查看每列的非空值数量、数据类型和内存占用,非常有用。df.describe()
: 对数值型列进行描述性统计(均值、标准差、最大最小值等),快速掌握数据分布。print("\n--- 数据概览 ---") print(df.info()) print("\n--- 描述性统计 ---") print(df.describe())
-
查看唯一值和频次:
df['列名'].unique()
: 查看某一列的所有唯一值。df['列名'].value_counts()
: 统计某一列每个唯一值出现的次数,对于分类数据特别有用。print("\n--- 'Product Name' 列的唯一值 ---") print(df['Product Name'].unique()) print("\n--- 'Product Name' 列的销售数量统计 ---") print(df['Product Name'].value_counts())
-
简单筛选和聚合:
筛选数据:
df[df['列名'] > value]
可以按条件筛选行。-
分组聚合:
df.groupby('分组列')['聚合列'].sum()等,进行分组统计。# 筛选出销售额大于10000的记录 high_sales = df[df['Sales Amount'] > 10000] print("\n--- 销售额大于10000的记录(前5行) ---") print(high_sales.head()) # 按产品名称统计总销售额 total_sales_by_product = df.groupby('Product Name')['Sales Amount'].sum().sort_values(ascending=False) print("\n--- 各产品总销售额 ---") print(total_sales_by_product.head())
这些步骤构成了我处理Excel数据的基本流程。它们看似简单,但每一步都至关重要,能够帮助你从原始、混乱的数据中提炼出有价值的信息,为更深入的分析打下坚实的基础。










