Объедините несколько листов из нескольких книг Excel в один кадр данных Pandas - PullRequest
0 голосов
/ 04 апреля 2019

Я настраиваю конвейер данных для данных от одного из наших арендаторов, который доставляет данные в файлы 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 Ответ

1 голос
/ 04 апреля 2019

Вы можете использовать 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...