Pandalar: Excel dosyasındaki sayfa listesine bakma


144

Panda'nın yeni sürümü Excel dosyalarını yüklemek için aşağıdaki arabirimi kullanır :

read_excel('path_to_file.xls', 'Sheet1', index_col=None, na_values=['NA'])

ama mevcut sayfaları bilmiyorsam ne olur?

Örneğin, aşağıdaki sayfalarda bulunan excel dosyalarıyla çalışıyorum

Veri 1, Veri 2 ..., Veri N, foo, çubuk

ama Na priori bilmiyorum .

Pandalar'da bir excel belgesinden sayfa listesini almanın herhangi bir yolu var mı?

Yanıtlar:


253

Yine de ExcelFile sınıfını (ve sheet_namesniteliğini) kullanabilirsiniz:

xl = pd.ExcelFile('foo.xls')

xl.sheet_names  # see all sheet names

xl.parse(sheet_name)  # read a specific sheet to DataFrame

daha fazla seçenek için ayrıştırma belgelerine bakın ...


1
Teşekkürler @Andy. Sorabilir miyim, Pandalar excel sayfasını içeri yüklüyor ExcelFilemu? Ayrıca, sayfa listesine baktığımda ve bunların N'sini yüklemeye karar verdiğimi read_excelvarsayalım, her bir sayfa için o noktada çağrı (yeni arayüz) yapmalı mıyım yoksa yapışmalı x1.parsemıyım?
Amelio Vazquez-Reina

2
Ben düşünüyorum ExcelFile dosya açıyorlar tutar (ve hepsini okumaz), ben ayrıştırma kullanarak (ve sadece bir kez dosyasını açarken) burada en mantıklı düşünüyorum. tbh read_excel'in gelişini kaçırdım!
Andy Hayden

6
Daha önce burada bahsetti , ancak DataFrames sözlüğünü tutmak istiyorum{sheet_name: xl.parse(sheet_name) for sheet_name in xl.sheet_names}
Andy Hayden

2
Size daha fazla oy verebilseydim, bu pandaların birden fazla sürümünde de çalışır! (API'yı neden bu kadar sık ​​değiştirmeyi sevdiklerini bilmiyorum) Beni ayrıştırma işlevine yönlendirdiğiniz için teşekkürler, işte şu anki bağlantı: pandas.pydata.org/pandas-docs/stable/generated/…
Ezekiel Kruglick

3
@NicholasLu downvote gereksizdi, bu cevap 2013'ten! Bununla birlikte, ExcelFile excel dosyalarını ayrıştırmanın orijinal yolu iken, kullanımdan kaldırılmamıştır ve bunu yapmak için mükemmel bir şekilde geçerli kalır.
Andy Hayden

37

İkinci parametreyi (sayfa adı) açıkça Yok olarak belirtmelisiniz. bunun gibi:

 df = pandas.read_excel("/yourPath/FileName.xlsx", None);

"df" DataFrames sözlüğü olarak tüm sayfalar, bunu çalıştırarak doğrulayabilirsiniz:

df.keys()

böyle sonuç:

[u'201610', u'201601', u'201701', u'201702', u'201703', u'201704', u'201705', u'201706', u'201612', u'fund', u'201603', u'201602', u'201605', u'201607', u'201606', u'201608', u'201512', u'201611', u'201604']

daha fazla ayrıntı için lütfen panda dokümanına bakın: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html


3
Bu gereksiz bir şekilde her sayfayı zorunlu olmayan bir DataFrame olarak ayrıştırır. "Bir xls / xlsx dosyası nasıl okunur" farklı bir sorudur .
Andy Hayden

7
@AndyHayden verimli olmayabilir, ancak tüm sayfaları önemsiyorsanız veya ek yükü umursamıyorsanız en iyisi olabilir.
CodeMonkey

8

@ DivingTobi'nin cevabından esinlenerek bulduğum en hızlı yol bu. Tüm xlrd, openpyxl veya pandalara dayalı cevaplar benim için yavaştır, çünkü hepsi önce tüm dosyayı yükler.

from zipfile import ZipFile
from bs4 import BeautifulSoup  # you also need to install "lxml" for the XML parser

with ZipFile(file) as zipped_file:
    summary = zipped_file.open(r'xl/workbook.xml').read()
soup = BeautifulSoup(summary, "xml")
sheets = [sheet.get("name") for sheet in soup.find_all("sheet")]

3

@Dhwanil_shah kullanıcısının cevabı üzerine inşa ederek, tüm dosyayı çıkarmanıza gerek yoktur. İle zf.openkendisine doğrudan sıkıştırılmış dosyadan okumak mümkündür.

import xml.etree.ElementTree as ET
import zipfile

def xlsxSheets(f):
    zf = zipfile.ZipFile(f)

    f = zf.open(r'xl/workbook.xml')

    l = f.readline()
    l = f.readline()
    root = ET.fromstring(l)
    sheets=[]
    for c in root.findall('{http://schemas.openxmlformats.org/spreadsheetml/2006/main}sheets/*'):
        sheets.append(c.attrib['name'])
    return sheets

Ardışık iki readline s çirkin, ancak içerik metnin yalnızca ikinci satırında. Tüm dosyayı ayrıştırmaya gerek yok.

Bu çözüm, read_excelsürümden çok daha hızlı ve büyük olasılıkla tam özü sürümünden daha hızlı görünüyor .


Hayır, .xls tamamen farklı bir dosya biçimidir, bu nedenle bu kodun çalışmasını beklemem.
divingTobi

2

Ben xlrd, pandalar, openpyxl ve diğer kütüphaneleri denedim ve hepsi tüm dosyayı okurken dosya boyutu arttıkça üstel zaman alıyor gibi görünüyor. 'On_demand' kullandıkları yukarıda belirtilen diğer çözümler benim için çalışmadı. Başlangıçta sayfa adlarını almak istiyorsanız, xlsx dosyaları için aşağıdaki işlev çalışır.

def get_sheet_details(file_path):
    sheets = []
    file_name = os.path.splitext(os.path.split(file_path)[-1])[0]
    # Make a temporary directory with the file name
    directory_to_extract_to = os.path.join(settings.MEDIA_ROOT, file_name)
    os.mkdir(directory_to_extract_to)

    # Extract the xlsx file as it is just a zip file
    zip_ref = zipfile.ZipFile(file_path, 'r')
    zip_ref.extractall(directory_to_extract_to)
    zip_ref.close()

    # Open the workbook.xml which is very light and only has meta data, get sheets from it
    path_to_workbook = os.path.join(directory_to_extract_to, 'xl', 'workbook.xml')
    with open(path_to_workbook, 'r') as f:
        xml = f.read()
        dictionary = xmltodict.parse(xml)
        for sheet in dictionary['workbook']['sheets']['sheet']:
            sheet_details = {
                'id': sheet['@sheetId'],
                'name': sheet['@name']
            }
            sheets.append(sheet_details)

    # Delete the extracted files directory
    shutil.rmtree(directory_to_extract_to)
    return sheets

Tüm xlsx temel olarak sıkıştırılmış dosyalar olduğundan, temel xml verilerini ayıklıyoruz ve çalışma kitabından doğrudan sayfa kitabını okuyoruz, bu da kitaplık işlevleriyle karşılaştırıldığında saniyenin bir kısmını alıyor.

Karşılaştırma: (4 sayfalık 6mb xlsx dosyasında)
Pandalar, xlrd: 12 saniye
openpyxl: 24 saniye
Önerilen yöntem: 0.4 saniye

İhtiyacım sadece sayfa adlarını okumak olduğu için, tüm zamanları okumak için gereksiz ek yük beni rahatsız ediyordu, bunun yerine bu yolu seçtim.


Kullandığınız modüller nelerdir?
Daniel

@Daniel Yalnızca zipfiledahili bir modül xmltodictolan ve XML'i kolayca yinelenebilir bir sözlüğe dönüştürmek için kullandım. Her ne kadar içindeki dosyaları çıkarmadan aynı dosyayı okuyabileceğiniz @ divingTobi'nin aşağıdaki cevabına bakabilirsiniz.
Dhwanil shah

Openpyxl'i read_only bayrağıyla denediğimde çok daha hızlı (5 MB dosyam için 200X daha hızlı). load_workbook(excel_file).sheetnamesortalama 39.6 load_workbook(excel_file, read_only=True).sheetnamesms.
flutefreak7

0
from openpyxl import load_workbook

sheets = load_workbook(excel_file, read_only=True).sheetnames

5MB Excel dosyası için çalışıyorum load_workbook, read_onlybayrak olmadan 8.24s aldı. İle read_onlybayrak sadece 39.6 ms sürmüştür. Hala bir Excel kütüphanesi kullanmak istiyorsanız ve bir xml çözümüne düşmüyorsanız, bu tüm dosyayı ayrıştıran yöntemlerden çok daha hızlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.