Объединение листов Excel в несколько циклов

1

У меня есть несколько книг Excel, каждая из которых содержит несколько рабочих листов, которые я хотел бы объединить.

Я создал два набора циклов (один, один, один для), чтобы читать строки для каждого листа в данной книге, а затем делать то же самое для всех книг.

Я попытался сделать это на подмножестве, и, похоже, он работает до тех пор, пока я не попытаюсь объединить два набора, используя функцию pd.concat. Приведенная ошибка

TypeError: первый аргумент должен быть итерабельным из объектов pandas, вы передали объект типа "DataFrame",

Любая идея, что я делаю неправильно?

import pandas as pd    

d = 2013
numberOfSheets = 5

while d < 2015:
    #print(str(d) + ' beginning')
    f ='H:/MyDocuments/Z Project Work/scriptTest ' + str(d) + '.xlsx'  
    for i in range(1,numberOfSheets+1):
        data = pd.read_excel(f, sheetname = 'Table '+str(i), header=None) 
        print(i)
        df.append(data)   

    print(str(d) + ' complete')
    print(df)
    d += 1

df = pd.concat(df)
print(df)

final = "H:/MyDocuments/Z Project Work/mergedfile.xlsx" 
df.to_excel(final)
Теги:
pandas

3 ответа

2
Лучший ответ

Как говорит ошибка, pd.concat() требует итерации, как и список: pd.concat([df1, df2]) объединяет df1 и df2 вдоль оси по умолчанию 0, что означает, что df2 добавляется к нижней части df1,

Необходимо решить две проблемы:

  1. Цикл for ссылается на df перед назначением ему чего-либо.
  2. Переменная df перезаписывается каждой итерацией цикла for.

Один из способов - создать пустой список DataFrames перед циклами, затем добавить DataFrames в этот список и, наконец, объединить все DataFrames в этом списке. Что-то вроде этого:

import pandas as pd    

d = 2013
numberOfSheets = 5
dfs = []

while d < 2015:
    #print(str(d) + ' beginning')
    f ='H:/MyDocuments/Z Project Work/scriptTest ' + str(d) + '.xlsx'  
    for i in range(1, numberOfSheets + 1):
        data = pd.read_excel(f, sheetname='Table ' + str(i), header=None) 
        print(i)
        dfs.append(data)

    print(str(d) + ' complete')
    print(df)
    d += 1

# ignore_index=True gives the result a default IntegerIndex 
# starting from 0
df_final = pd.concat(dfs, ignore_index=True)
print(df_final)

final_path = "H:/MyDocuments/Z Project Work/mergedfile.xlsx" 
df_final.to_excel(final_path)
2

Поскольку я не могу комментировать, я оставлю это в качестве ответа: вы можете ускорить этот код, открыв файл, после чего разберем книгу, чтобы получить каждый лист. Следует сохранять секунду или две с каждой итерации, так как открытие файла Excel занимает самое большое время. Вот код, который может помочь.

Примечание: установка sheet_name=None вернет ВСЕ листы в книге:

dfs = {<sheetname1>: <DataFrame1>, <sheetname2>: <DataFrame2>, etc.}  

Здесь код:

xl = pd.ExcelFile(fpath)
dfs = xl.parse(sheetname=None, header=None)

for i, df in enumerate(dfs):
    <do stuff with each, if you want>
    print('Sheet {0} looks like:\n{1}'.format(i+1, df))
1

Спасибо вам обоим. Я принял ответ, который касался конкретного вопроса, но был в состоянии использовать второй ответ и некоторый дополнительный googling после этого (например, glob), чтобы исправить исходный код, и автоматизировать более полную независимость от количества книг или рабочих листов.

Окончательный вариант вышеизложенного ниже:

import pandas as pd
import glob
#import numpy as np
#import os, collections, csv
#from os.path import basename    

fpath = "H:/MyDocuments/Z Project Work/"

dfs = []
files = glob.glob(fpath+'*.xlsx') 

for f in files:
    xl = pd.ExcelFile(f) 
    xls = xl.parse(sheetname=None, header=0)
    for i, df in enumerate(xls):
        print(i)    
        dfs.append(xls[df])   

    print(f+ ' complete')

df_final = pd.concat(dfs, ignore_index=True)

final = "H:/MyDocuments/Z Project Work/mergedfile.xlsx" 
df_final.to_excel(final)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню