将多个Excel工作簿中的多个工作表合并到一个Pandas数据框中

时间:2019-04-04 05:12:01

标签: python excel pandas dataframe merge

我正在为来自一个租户的数据建立数据管道,这些租户以Excel文件的形式提供数据:每周一个工作簿,而工作簿中的每一页代表一天。我们无法控制格式,但是过程必须足够灵活以处理工作簿和工作表中的各种名称。这也需要在Python中进行,因为我们不允许执行宏或VBA(不是我的政策)。

我已经尝试过在循环中使用pd.read_Excel(),但是它当前会以数据帧字典的形式返回输出,并且pd.concat()函数会引发错误。我需要定义一个执行以下操作的过程:

  1. 从目录中拉出工作簿列表,然后
  2. 从该工作簿中提取工作表名称列表,然后
  3. 遍历每张纸并将数据读取到一个空的数据框中,然后
  4. 为每个工作簿重复,将每个工作簿的结果附加到最终的单个数据框中。

最终,将其设置为每月脚本,该脚本将指向要导入最新数据的目录。在运行全年的数据之前,我目前正在一些工作簿上对其进行测试。代码中的某些打印功能仅用于临时输出检查。 我当前的代码,并抛出错误:

import pandas as pd
import os

# Once functioning, re-implement as a def
# Get list of Excel files in the working directory
os.getcwd()
os.chdir('d:\\projects\\chassis\\data')
os.getcwd()
files = os.listdir()
wkbks = [f for f in files if f[-4:] =='xlsx']

输出:['1-1 through 1-5.xlsx', '1-14 through 1-19.xlsx', '1-21 through 1-26.xlsx']

如果我在工作簿的完整列表上运行它:

# skiprows and usecols are to handle original sheet format, which has extraneous header rows
df = pd.read_excel(wkbks, sheet_name=None, ignore_index=True, skiprows=6, usecols=8)
cdf = pd.concat(df.values())

它引发错误:Invalid file path or buffer object type: <class 'list'>

如果我仅使用df = pd.read_excel(wkbks[1], sheet_name=None, ignore_index=True, skiprows=6, usecols=8)在单个工作簿上运行它,那么它将返回一个列表字典,如下所示:

OrderedDict([('Mon 1.14 to 1.15',     Carrier ID                              Carrier Name  Mission  \
0         XPOR                   XPO PORT SERVICES, INC.  Dropoff   
1         CCOO                      DECO LOGISTICS, INC.  Dropoff   
2         AMPF          AMERICAN PACIFIC FORWARDERS, INC  Dropoff   
3         GPON           GOLD POINT TRANSPORTATION, INC.  Dropoff   
4         FXTR                  FOX TRANSPORTATION, INC.  Dropoff   

尝试将此字典与df2 = pd.concat([pd.concat(v) for k,v in df.items()])串联会引发错误:TypeError: first argument must be an iterable of pandas objects, you passed an object of type "DataFrame"

我觉得这接近工作,但是我缺少以下步骤:

  1. 一次处理所有文件列表,而无需处理一个文件 一次
  2. 正确转换数据帧的字典。

1 个答案:

答案 0 :(得分:1)

您可以对文件夹中的所有文件使用glob,然后由concat和最后DataFrame.append到最后DataFrame一起加入:

import glob

all_data = pd.DataFrame()
path = 'd:/projects/chassis/data/*.xlsx'
for f in glob.glob(path):
    df = pd.read_excel(f, sheet_name=None, ignore_index=True, skiprows=6, usecols=8)
    cdf = pd.concat(df.values())
    all_data = all_data.append(cdf,ignore_index=True)
print(all_data)