【问题标题】:pandas read_excel multiple tables on the same sheetpandas read_excel 同一张表上的多个表
【发布时间】:2023-03-30 20:55:02
【问题描述】:

是否可以使用 pandas 从工作表 excel 文件中读取多个表格? 就像是: 从第 0 行到第 100 行读取 table1 从第 102 行到第 202 行读取 table2 ...

【问题讨论】:

  • 为什么不直接读完,然后在 python 中分离到不同的DataFrames?
  • 我不知道如何才能做到这一点。
  • @bsd,你知道总行数吗?

标签: python excel pandas dataframe


【解决方案1】:

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

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
  • 干得好@Rotem
【解决方案2】:

假设我们有以下 Excel 文件:

解决方案:我们正在解析第一张表(索引: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

【讨论】:

    【解决方案3】:

    首先读入整个csv文件:

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

    然后获取各个帧,例如使用:

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

    【讨论】:

    • 如果是 CSV 文件,我们可以简单地使用 skiprowsnrows 参数。不幸的是,nrows 没有为pd.read_excel 实现
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2014-07-11
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多