pandas读取Excel文件中同一工作表的多个表格

20

使用Pandas可以从Excel文件中读取多个表格吗? 类似这样: 从第0行到第100行读取table1 从第102行到第202行读取table2 ...


1
为什么不直接在Python中将所有内容读入,然后分离到不同的“DataFrame”中呢? - splinter
我不确定如何实现这个。 - bsd
@bsd,你事先知道总行数吗? - MaxU - stand with Ukraine
3个回答

20

我编写了以下代码,可以自动识别多个表格,以便您处理许多文件并且不想查看每个文件以获取正确的行号。该代码还会在每个表格上方查找非空行,并将其读取为表格元数据。

def parse_excel_sheet(file, sheet_name=0, threshold=5):
    '''parses multiple tables from an excel sheet into multiple data frame objects. Returns [dfs, df_mds], where dfs is a list of data frames and df_mds their potential associated metadata'''
    xl = pd.ExcelFile(file)
    entire_sheet = xl.parse(sheet_name=sheet_name)

    # count the number of non-Nan cells in each row and then the change in that number between adjacent rows
    n_values = np.logical_not(entire_sheet.isnull()).sum(axis=1)
    n_values_deltas = n_values[1:] - n_values[:-1].values

    # define the beginnings and ends of tables using delta in n_values
    table_beginnings = n_values_deltas > threshold
    table_beginnings = table_beginnings[table_beginnings].index
    table_endings = n_values_deltas < -threshold
    table_endings = table_endings[table_endings].index
    if len(table_beginnings) < len(table_endings) or len(table_beginnings) > len(table_endings)+1:
        raise BaseException('Could not detect equal number of beginnings and ends')

    # look for metadata before the beginnings of tables
    md_beginnings = []
    for start in table_beginnings:
        md_start = n_values.iloc[:start][n_values==0].index[-1] + 1
        md_beginnings.append(md_start)

    # make data frames
    dfs = []
    df_mds = []
    for ind in range(len(table_beginnings)):
        start = table_beginnings[ind]+1
        if ind < len(table_endings):
            stop = table_endings[ind]
        else:
            stop = entire_sheet.shape[0]
        df = xl.parse(sheet_name=sheet_name, skiprows=start, nrows=stop-start)
        dfs.append(df)

        md = xl.parse(sheet_name=sheet_name, skiprows=md_beginnings[ind], nrows=start-md_beginnings[ind]-1).dropna(axis=1)
        df_mds.append(md)
    return dfs, df_mds

df_mds列表是什么?因为所有的df都被放置在dfs中。 - bl79
1
做得好,@Rotem。 - ArKan
1
对我来说抛出以下异常:ValueError: 'nrows' 必须是一个大于等于0的整数。 - Shihab Ullah
这个函数中的“threshold”是什么? - NoobVB
1
@NoobVB阈值变量是猜测确定表格开始和结束之间差异的变量。在这个意义上,它是一个棘手的启发式方法。变量n_values和n_values_deltas提供了一些提示,因为它们是一行中所有非空元素的总和,后跟前一行和当前行之间的差异。本质上,它是一种“边缘检测”的形式,您可以想象一个索引的阶跃函数在x轴上,而delta在y轴上,阈值是正x和-x轴上的常数线。当越过时,定义了一个新的表格。 - ZdWhite
显示剩余2条评论

16

假设我们有以下Excel文件:

enter image description here

解决方案: 我们正在解析第一个工作表(索引:0)。

xl = pd.ExcelFile(fn)
nrows = xl.book.sheet_by_index(0).nrows

df1 = xl.parse(0, skipfooter= nrows-(10+1)).dropna(axis=1, how='all')
df2 = xl.parse(0, skiprows=12).dropna(axis=1, how='all')

编辑: skip_footer 被替换成 skipfooter

结果:

In [123]: df1
Out[123]:
    a   b   c
0  78  68  33
1  62  26  30
2  99  35  13
3  73  97   4
4  85   7  53
5  80  20  95
6  40  52  96
7  36  23  76
8  96  73  37
9  39  35  24

In [124]: df2
Out[124]:
   c1  c2  c3 c4
0  78  88  59  a
1  82   4  64  a
2  35   9  78  b
3   0  11  23  b
4  61  53  29  b
5  51  36  72  c
6  59  36  45  c
7   7  64   8  c
8   1  83  46  d
9  30  47  84  d

5

首先读取整个 csv 文件:

import pandas as pd
df = pd.read_csv('path_to\\your_data.csv')

接着,可以通过以下方式获取单独的帧:

df1 = df.iloc[:100,:]
df2 = df.iloc[100:200,:]

1
如果这个是一个CSV文件,我们可以简单地使用skiprowsnrows参数来处理。不幸的是,pd.read_excel函数还没有实现nrows参数。 - MaxU - stand with Ukraine

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