使用Pandas的pd.read_excel()函数读取同一工作簿中的多个工作表

404
我有一个大的电子表格文件 (.xlsx),正在使用 Python 的 Pandas 进行处理。需要从其中两个选项卡(表)中获取数据。其中一个选项卡含有大量数据,而另一个选项卡只有几个方格。
当我在任何工作表上使用pd.read_excel()时,看起来整个文件都被加载了 (不仅仅是我感兴趣的工作表)。那么,当我使用该方法两次 (每次一张纸),即使我们只使用指定的纸张,我也必须承受整个工作簿被读入两次的后果。
如何使用 pd.read_excel() 仅加载特定的选项卡?

我在这个其他帖子中举了一个例子:https://dev59.com/olYN5IYBdhLWcg3wb3wX#66280555 - neosergio
14个回答

584

尝试使用pd.ExcelFile

xls = pd.ExcelFile('path_to_file.xls')
df1 = pd.read_excel(xls, 'Sheet1')
df2 = pd.read_excel(xls, 'Sheet2')

如@HaPsantran所述,在ExcelFile()调用期间会读取整个Excel文件(似乎没有绕过这一点的方法)。这仅仅是为了使您不必每次访问新工作表时都要重新读取同一个文件。

请注意,pd.read_excel()函数的sheet_name参数可以是工作表名称(如上所示),指定工作表编号的整数(例如0、1等),工作表名称或索引的列表,或者是None。如果提供了一个列表,则返回一个字典,其中键为工作表名称/索引,值为数据框。默认情况下,只返回第一个工作表(即sheet_name=0)。

如果指定了None,则返回所有工作表,即{sheet_name:dataframe}字典形式。


7
就目前我测试的情况来看,似乎第一行会加载所有内容,所以没有有效的方法仅加载单个表格,但至少获取多个表格不需要多次加载整个表格。 - HaPsantran
3
这个答案已经被Pandas弃用,在v0.21.0版本中会出现错误。应该使用@Mat0kan提供的答案来替代它。 - DStauffman
4
这仍然对我有效,并且代码和文档中没有任何迹象表明它已被弃用。如果您在使用它时遇到问题,我建议您在Pandas或xlrd的Github上提交一个问题(Pandas使用的Python Excel解析库)。 - Noah
3
提醒一下.. pd.ExcelFile 使用 xlrd,但是从2020年12月开始,xlrd不再支持xls或xlsx文件。您可以通过 xls = pd.ExcelFile('path_to_file.xls' engine='openpyxl') 来解决这个问题。 - Eme Eme
2
@EmeEme,FYI,较新版本的pandas默认使用openpyxl。 - Noah
显示剩余6条评论

260

有几个选项:

将所有表格直接读入有序字典中。

import pandas as pd

# for pandas version >= 0.21.0
sheet_to_df_map = pd.read_excel(file_name, sheet_name=None)

# for pandas version < 0.21.0
sheet_to_df_map = pd.read_excel(file_name, sheetname=None)

直接将第一个表格读入数据框中

df = pd.read_excel('excel_file_path.xls')
# this will read the first sheet into df

读取Excel文件并获取工作表列表,然后选择并加载这些工作表。

xls = pd.ExcelFile('excel_file_path.xls')

# Now you can list all sheets in the file
xls.sheet_names
# ['house', 'house_extra', ...]

# to read just one sheet to dataframe:
df = pd.read_excel(file_name, sheet_name="house")

读取所有工作表并将其存储在字典中。与第一个相同,但更明确。

# to read all sheets to a map
sheet_to_df_map = {}
for sheet_name in xls.sheet_names:
    sheet_to_df_map[sheet_name] = xls.parse(sheet_name)
    # you can also use sheet_index [0,1,2..] instead of sheet name.

感谢 @ihightower 指出了读取所有工作表的方法,@toto_tico、@red-headphone 指出了版本问题。

sheetname:字符串、整数、字符串/整数混合列表或 None,默认为 0 自版本 0.21.0 起已弃用:请使用 sheet_name 替代 源链接


26
在我使用的最新版本的Pandas(0.20.3)中,要读取所有工作表并将其映射到一个字典中,只需执行以下操作:df_sheet_map = pd.read_excel(file_fullpath, sheetname=None),这将自动将所有工作表存储在一个字典中。要像这样访问单个工作表作为数据框:df_sheet_map['house'] - ihightower
@ihightower 这是一个字典,而不是地图。我现在回答是因为我曾经在这个函数上挣扎过,因为在最近的 pandas 版本中,他们取消了 read_excel 中 kwargs 的支持,我正在尝试绕过它。 - Daneel R.

45

您还可以使用工作表的索引:

xls = pd.ExcelFile('path_to_file.xls')
sheet1 = xls.parse(0)

将提供第一个工作表。对于第二个工作表:

sheet2 = xls.parse(1)

9
如果您需要工作表名称列表,请键入xls.sheet_names。 - Stefano Fedele

45

您也可以将工作表名称指定为参数:

data_file = pd.read_excel('path_to_file.xls', sheet_name="sheet_name")

仅上传工作表"sheet_name"


31

根据使用情况,有多种选项:

  1. 如果不知道工作表的名称。

  2. 如果工作表的名称不相关。

  3. 如果知道工作表的名称。

下面我们将仔细看一下每个选项。

请参见“备注”部分以获取诸如查找工作表名称等信息。


选项1

如果不知道工作表的名称。

# Read all sheets in your File
df = pd.read_excel('FILENAME.xlsx', sheet_name=None)
    
# Prints all the sheets name in an ordered dictionary
print(df.keys())

然后,根据想要读取的表格,可以将它们传递给特定的dataframe,例如:

sheet1_df = pd.read_excel('FILENAME.xlsx', sheet_name=SHEET1NAME)
sheet2_df = pd.read_excel('FILENAME.xlsx', sheet_name=SHEET2NAME)

选项二

如果名称不重要,而且人们只关心表格的位置。假设我们只需要第一个工作表。

# Read all sheets in your File
df = pd.read_excel('FILENAME.xlsx', sheet_name=None)

sheet1 = list(df.keys())[0]

那么,根据工作表名称,可以将其分别传递给特定的dataframe,例如:

sheet1_df = pd.read_excel('FILENAME.xlsx', sheet_name=SHEET1NAME)

选项三

这里我们将考虑知道工作表名称的情况。 在示例中,我们将假定有三个名为Sheet1Sheet2Sheet3的工作表。每个工作表中的内容都相同,并且如下所示

     0         1     2
0   85   January  2000
1   95  February  2001
2  105     March  2002
3  115     April  2003
4  125       May  2004
5  135      June  2005

根据目标不同,有多种方法:

  • 将所有内容存储在同一个数据框中。一种方法是按以下方式连接工作表:

sheets = ['Sheet1', 'Sheet2', 'Sheet3']
df = pd.concat([pd.read_excel('FILENAME.xlsx', sheet_name = sheet) for sheet in sheets], ignore_index = True)

[Out]:

      0         1     2
0    85   January  2000
1    95  February  2001
2   105     March  2002
3   115     April  2003
4   125       May  2004
5   135      June  2005
6    85   January  2000
7    95  February  2001
8   105     March  2002
9   115     April  2003
10  125       May  2004
11  135      June  2005
12   85   January  2000
13   95  February  2001
14  105     March  2002
15  115     April  2003
16  125       May  2004
17  135      June  2005

基本上,这就是 pandas.concat 的工作方式(来源):

enter image description here

  • 将每个表格存储在不同的数据框中(比如说,df1df2等)。

  • sheets = ['Sheet1', 'Sheet2', 'Sheet3']
    
    for i, sheet in enumerate(sheets):
        globals()['df' + str(i + 1)] = pd.read_excel('FILENAME.xlsx', sheet_name = sheet)
    
    [Out]:
    
    # df1
         0         1     2
    0   85   January  2000
    1   95  February  2001
    2  105     March  2002
    3  115     April  2003
    4  125       May  2004
    5  135      June  2005
    
    # df2
         0         1     2
    0   85   January  2000
    1   95  February  2001
    2  105     March  2002
    3  115     April  2003
    4  125       May  2004
    5  135      June  2005
    
    # df3
         0         1     2
    0   85   January  2000
    1   95  February  2001
    2  105     March  2002
    3  115     April  2003
    4  125       May  2004
    5  135      June  2005
    

    注意事项:

    • 如果想要知道表格的名称,可以使用 ExcelFile 类,如下所示:

    sheets = pd.ExcelFile('FILENAME.xlsx').sheet_names
    
    [Out]: ['Sheet1', 'Sheet2', 'Sheet3']
    
  • 在这种情况下,假设文件FILENAME.xlsx和正在运行的脚本位于同一个目录中。

    • 如果文件位于当前目录中名为Data的文件夹中,则可以使用r'./Data/FILENAME.xlsx'创建一个变量,例如path,如下所示:

       path = r'./Data/Test.xlsx'
      
       df = pd.read_excel(r'./Data/FILENAME.xlsx', sheet_name=None)
      
  • 这篇文章可能会对你有所帮助。


  • 15
    pd.read_excel('filename.xlsx') 
    

    默认情况下读取工作簿中的第一个表。

    pd.read_excel('filename.xlsx', sheet_name = 'sheetname') 
    

    阅读工作簿的特定表格并

    pd.read_excel('filename.xlsx', sheet_name = None) 
    

    将Excel中的所有工作表作为OrderedDict类型的嵌套数据帧读入Pandas数据帧,所有工作表作为数据帧收集在数据帧内,并且其类型为OrderedDict。


    15

    如果您有兴趣阅读所有表格并将它们合并在一起。最好且最快的方式是

    sheet_to_df_map = pd.read_excel('path_to_file.xls', sheet_name=None)
    mdf = pd.concat(sheet_to_df_map, axis=0, ignore_index=True)
    

    这将把所有的工作表转换成一个名为m_df的数据框。


    在这种情况下,您将如何切分特定于工作表的数据?由于我们没有任何用于工作表名称的列。 - Himanshu

    5
    你可以使用以下代码读取所有的工作表。
    import pandas as pd
    file_instance = pd.ExcelFile('your_file.xlsx')
    
    main_df = pd.concat([pd.read_excel('your_file.xlsx', sheet_name=name) for name in file_instance.sheet_names] , axis=0)
    

    如果您不想为每个工作表设置不同的索引编号,可以在末尾添加.reset_index(drop=True)。 - outcast_dreamer

    5
    如果:
    • 您需要多个工作表,但不是全部,且
    • 您需要单个数据框作为输出
    那么,您可以传递一个工作表名称列表。您可以手动填充该列表:
    import pandas as pd
        
    path = "C:\\Path\\To\\Your\\Data\\"
    file = "data.xlsx"
    sheet_lst_wanted = ["01_SomeName","05_SomeName","12_SomeName"] # tab names from Excel
    
    ### import and compile data ###
        
    # read all sheets from list into an ordered dictionary    
    dict_temp = pd.read_excel(path+file, sheet_name= sheet_lst_wanted)
    
    # concatenate the ordered dict items into a dataframe
    df = pd.concat(dict_temp, axis=0, ignore_index=True)
    

    或者

    如果您所需的工作表具有公共命名约定,并且还允许您区分不需要的工作表,那么可以进行一些自动化操作:

    # substitute following block for the sheet_lst_wanted line in above block
    
    import xlrd
    
    # string common to only worksheets you want
    str_like = "SomeName" 
        
    ### create list of sheet names in Excel file ###
    xls = xlrd.open_workbook(path+file, on_demand=True)
    sheet_lst = xls.sheet_names()
        
    ### create list of sheets meeting criteria  ###
    sheet_lst_wanted = []
        
    for s in sheet_lst:
        # note: following conditional statement based on my sheets ending with the string defined in sheet_like
        if s[-len(str_like):] == str_like:
            sheet_lst_wanted.append(s)
        else:
            pass
    

    我认为这应该是被接受的答案!如果你只需要读取几个表格,你也可以使用元组解包。df1, df2 = pd.read_excel(filepath, sheet_name=["sheet1", "sheet2"]).values() - Evan

    4
    df = pd.read_excel('FileName.xlsx', 'SheetName')
    

    这将从文件FileName.xlsx中读取名为SheetName的表格。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接