Używanie Pandas do pd.read_excel () dla wielu arkuszy tego samego skoroszytu

166

Mam duży plik arkusza kalkulacyjnego (.xlsx), który przetwarzam za pomocą pand w języku Python. Zdarza się, że potrzebuję danych z dwóch zakładek w tym dużym pliku. Jedna z zakładek zawiera mnóstwo danych, a druga to tylko kilka kwadratowych komórek.

Kiedy używam pd.read_excel () na dowolnym arkuszu, wygląda na to, że załadowany jest cały plik (nie tylko arkusz, który mnie interesuje). Więc kiedy używam tej metody dwa razy (raz dla każdego arkusza), efektywnie muszę cierpieć na dwukrotne przeczytanie całego skoroszytu (nawet jeśli używamy tylko określonego arkusza).

Czy używam go źle, czy jest to po prostu ograniczone w ten sposób?

Dziękuję Ci!

HaPsantran
źródło

Odpowiedzi:

244

Spróbuj pd.ExcelFile:

xls = pd.ExcelFile('path_to_file.xls')
df1 = pd.read_excel(xls, 'Sheet1')
df2 = pd.read_excel(xls, 'Sheet2')

Jak zauważył @HaPsantran, cały plik Excel jest wczytywany podczas ExcelFile()połączenia (wydaje się, że nie ma sposobu na obejście tego). Dzięki temu nie musisz czytać tego samego pliku za każdym razem, gdy chcesz uzyskać dostęp do nowego arkusza.

Zauważ, że sheet_nameargumentem do pd.read_excel()może być nazwa arkusza (jak wyżej), liczba całkowita określająca numer arkusza (np. 0, 1 itd.), Lista nazw arkuszy lub indeksów lub None. Jeśli podano listę, zwraca słownik, w którym kluczami są nazwy / indeksy arkuszy, a wartościami są ramki danych. Domyślnie po prostu zwraca pierwszy arkusz (tj.sheet_name=0 .).

Jeśli Nonepodano, wszystkie arkusze są zwracane jako {sheet_name:dataframe}słownik.

Noe
źródło
4
FWIW, wygląda na to, że (ostatnio to testowałem) pierwsza linia ładuje wszystko , więc nie ma sposobu, aby efektywnie wciągnąć tylko jeden arkusz, ale przynajmniej uzyskanie wielu arkuszy nie wymaga wielokrotnego obciążenia całego arkusza.
HaPsantran
1
Ta odpowiedź została wycofana przez pandy i teraz ulega awarii w wersji 0.21.0. Powinien zostać zastąpiony tym, który podał @ Mat0kan.
DStauffman
1
@DStauffman To nadal działa dobrze dla mnie i nie widzę żadnych wskazówek z kodu ani dokumentów, że jest to przestarzałe. Jeśli masz z tym problem, zgłosiłbym problem na githubie dla pand lub xlrd (biblioteka parsowania Pythona Excela używana przez pandy)
Noah
@Noah, dzięki, przyjrzałem się temu trochę więcej i masz rację, nadal działa, dopóki używam, sheet_namea nie sheetname. Nie zdawałem sobie sprawy, że to przestarzała część, ponieważ nadal działała na metodzie read_excel, ale nie na metodzie parsowania.
DStauffman
@Noah Rzeczywiście ładna odpowiedź. Czy istnieje sposób na znalezienie aktywnej komórki w czytanym arkuszu programu Excel?
Eswar
97

Istnieją 3 opcje:

Czytaj wszystkie arkusze bezpośrednio w uporządkowanym słowniku.

import pandas as pd

# for pandas version >= 0.21.0
sheet_to_df_map = pd.read_excel(file_name, sheet_name=None)

# for pandas version < 0.21.0
sheet_to_df_map = pd.read_excel(file_name, sheetname=None)

Dzięki @ihightower za wskazanie tego i @toto_tico za wskazanie problemu z wersją.

Przeczytaj pierwszy arkusz bezpośrednio do ramki danych

df = pd.read_excel('excel_file_path.xls')
# this will read the first sheet into df

Przeczytaj plik Excela i uzyskaj listę arkuszy. Następnie wybierz i załaduj arkusze.

xls = pd.ExcelFile('excel_file_path.xls')

# Now you can list all sheets in the file
xls.sheet_names
# ['house', 'house_extra', ...]

# to read just one sheet to dataframe:
df = pd.read_excel(file_name, sheetname="house")

Przeczytaj wszystkie arkusze i zapisz je w słowniku. Taki sam jak pierwszy, ale bardziej wyraźny.

# to read all sheets to a map
sheet_to_df_map = {}
for sheet_name in xls.sheet_names:
    sheet_to_df_map[sheet_name] = xls.parse(sheet_name)

Aktualizacja: Dzięki @toto_tico za wskazanie problemu z wersją.

nazwa_arkusza: ciąg, int, mieszana lista ciągów / int lub brak, domyślnie 0 Przestarzałe od wersji 0.21.0: Zamiast tego użyj linku źródłowego nazwa_arkusza

Vikash Singh
źródło
12
w najnowszych pandach, które mam (0.20.3), aby odczytać wszystkie arkusze do mapy .. wystarczy df_sheet_map = pd.read_excel(file_fullpath, sheetname=None), że arkusze w słowniku będą automatycznie .. i uzyskam dostęp do arkusza jako ramki danych w następujący sposób:df_sheet_map['house']
ihightower
32

Możesz również użyć indeksu dla arkusza:

xls = pd.ExcelFile('path_to_file.xls')
sheet1 = xls.parse(0)

poda pierwszy arkusz roboczy. dla drugiego arkusza:

sheet2 = xls.parse(1)
Elliott
źródło
7
Jeśli chcesz listę nazw arkuszy, wpisz po prostu xls.sheet_names
Stefano Fedele
28

Możesz również określić nazwę arkusza jako parametr:

data_file = pd.read_excel('path_to_file.xls', sheet_name="sheet_name")

prześle tylko arkusz "sheet_name".

Mat0kan
źródło
9
pd.read_excel('filename.xlsx') 

domyślnie przeczytaj pierwszy arkusz skoroszytu.

pd.read_excel('filename.xlsx', sheet_name = 'sheetname') 

przeczytaj konkretny arkusz skoroszytu i

pd.read_excel('filename.xlsx', sheet_name = None) 

czytaj wszystkie arkusze robocze z programu Excel do pandas dataframe, ponieważ typ OrderedDict oznacza zagnieżdżone ramki danych, wszystkie arkusze jako ramki danych zebrane wewnątrz dataframe i jego typ to OrderedDict.

Ashu007
źródło
1

Tak, niestety zawsze załaduje pełny plik. Jeśli robisz to wielokrotnie, prawdopodobnie najlepiej wyodrębnić arkusze do oddzielnych plików CSV, a następnie załadować je osobno. Możesz zautomatyzować ten proces za pomocą d6tstack, który dodaje również dodatkowe funkcje, takie jak sprawdzanie, czy wszystkie kolumny są równe we wszystkich arkuszach lub wielu plikach Excel.

import d6tstack
c = d6tstack.convert_xls.XLStoCSVMultiSheet('multisheet.xlsx')
c.convert_all() # ['multisheet-Sheet1.csv','multisheet-Sheet2.csv']

Zobacz przykłady programu d6tstack Excel

citynorman
źródło
0

Jeśli zapisałeś plik Excela w tym samym folderze, co program w Pythonie (adresowanie względne), wystarczy podać numer arkusza wraz z nazwą pliku. Składnia = pd.read_excel (nazwa pliku, nr arkusza) Przykład:

    data=pd.read_excel("wt_vs_ht.xlsx","Sheet2")
    print(data)
    x=data.Height
    y=data.Weight
    plt.plot(x,y,'x')
    plt.show()
Nikita Agarwala
źródło