Gấu trúc: Tra cứu danh sách các trang tính trong tệp excel


141

Phiên bản mới của Pandas sử dụng giao diện sau để tải các tệp Excel:

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

Nhưng nếu tôi không biết những tờ có sẵn thì sao?

Ví dụ: tôi đang làm việc với các tệp excel có các trang tính sau

Dữ liệu 1, Dữ liệu 2 ..., Dữ liệu N, foo, thanh

nhưng tôi không biết Nmột tiên nghiệm.

Có cách nào để lấy danh sách các trang tính từ một tài liệu excel trong Pandas không?

Câu trả lời:


250

Bạn vẫn có thể sử dụng lớp ExcelFile (và sheet_namesthuộc tính):

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

xl.sheet_names  # see all sheet names

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

xem tài liệu để phân tích cú pháp để có thêm tùy chọn ...


1
Cảm ơn @Andy. Tôi có thể hỏi, Pandas có tải bảng excel ExcelFilekhông? Ngoài ra, giả sử tôi tra cứu danh sách các trang tính và quyết định tải N của chúng, tôi có nên gọi điểm đó read_excel(giao diện mới) cho mỗi trang tính hay x1.parsekhông?
Amelio Vazquez-Reina

2
Tôi nghĩ ExcelFile giữ tệp mở (và không đọc hết), tôi nghĩ rằng sử dụng phân tích cú pháp (và chỉ mở tệp một lần) có ý nghĩa nhất ở đây. Tôi đã bỏ lỡ sự xuất hiện của read_excel!
Andy Hayden

6
Được đề cập trước đây , nhưng tôi muốn giữ một từ điển DataFrames bằng cách sử dụng{sheet_name: xl.parse(sheet_name) for sheet_name in xl.sheet_names}
Andy Hayden

2
Ước gì tôi có thể cung cấp cho bạn nhiều upvote hơn, điều này cũng hoạt động trên nhiều phiên bản của gấu trúc! (không biết tại sao họ lại như thay đổi API vì vậy thường xuyên) Cảm ơn bạn đã chỉ cho tôi vào chức năng phân tích, đây là liên kết hiện tại mặc dù: pandas.pydata.org/pandas-docs/stable/generated/...
Ezekiel Kruglick

3
@NicholasLu downvote là không cần thiết, câu trả lời này là từ năm 2013! Điều đó nói rằng, trong khi ExcelFile là cách ban đầu để phân tích các tệp excel thì nó không bị phản đối và vẫn là một cách hoàn toàn hợp lệ để làm điều này.
Andy Hayden

37

Bạn nên chỉ định rõ ràng tham số thứ hai (tên trang) là Không có. như thế này:

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

"df" là tất cả các trang tính như một từ điển của DataFrames, bạn có thể xác minh nó bằng cách chạy này:

df.keys()

kết quả như thế này:

[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']

vui lòng tham khảo tài liệu về gấu trúc để biết thêm chi tiết: https://pandas.pydata.org/pandas-docs/urdy/generated/pandas.read_excel.html


3
Điều này không cần thiết phân tích mọi trang tính dưới dạng DataFrame, không bắt buộc. "Cách đọc tệp xls / xlsx" là một câu hỏi khác .
Andy Hayden

7
@AndyHayden nó có thể không hiệu quả, nhưng nó có thể là tốt nhất nếu bạn quan tâm đến tất cả các tờ, hoặc bạn không quan tâm đến chi phí bổ sung.
CodeMonkey

8

Đây là cách nhanh nhất mà tôi đã tìm thấy, lấy cảm hứng từ câu trả lời của @ lặnTobi. Tất cả các câu trả lời dựa trên xlrd, openpyxl hoặc gấu trúc đều chậm đối với tôi, vì tất cả chúng đều tải toàn bộ tệp trước tiên.

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

Dựa trên câu trả lời của @dhwanil_shah, bạn không cần trích xuất toàn bộ tệp. Với zf.opennó có thể đọc từ một tệp nén trực tiếp.

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

Hai readlines liên tiếp là xấu, nhưng nội dung chỉ trong dòng thứ hai của văn bản. Không cần phải phân tích toàn bộ tập tin.

Giải pháp này dường như nhanh hơn nhiều so với read_excelphiên bản, và rất có thể cũng nhanh hơn phiên bản trích xuất đầy đủ.


Không, .xls là một định dạng tệp hoàn toàn khác, vì vậy tôi sẽ không mong đợi mã này hoạt động.
lặnTobi

2

Tôi đã thử xlrd, gấu trúc, openpyxl và các thư viện khác như vậy và tất cả chúng dường như mất thời gian theo cấp số nhân khi kích thước tệp tăng lên khi nó đọc toàn bộ tệp. Các giải pháp khác được đề cập ở trên nơi họ sử dụng 'on_demand' không hoạt động với tôi. Nếu bạn chỉ muốn lấy tên trang tính ban đầu, hàm sau sẽ hoạt động cho các tệp xlsx.

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

Vì tất cả các xlsx về cơ bản là các tệp nén, chúng tôi trích xuất dữ liệu xml bên dưới và đọc tên trang tính từ sổ làm việc chỉ mất một phần giây so với các hàm thư viện.

Điểm chuẩn: (Trên tệp xlsx
6mb có 4 tờ) Gấu trúc, xlrd: 12 giây
openpyxl: 24 giây
Phương pháp đề xuất: 0,4 giây

Vì yêu cầu của tôi chỉ là đọc tên trang tính, nên việc đọc toàn bộ thời gian không cần thiết đã làm tôi khó chịu nên tôi đã chọn con đường này để thay thế.


Các mô-đun bạn đang sử dụng là gì?
Daniel

@Daniel Tôi chỉ sử dụng zipfilemột mô-đun được xây dựng và xmltodicttôi đã sử dụng để chuyển đổi XML thành một từ điển có thể lặp lại dễ dàng. Mặc dù bạn có thể xem câu trả lời của @ lặnTobi bên dưới nơi bạn có thể đọc cùng một tệp mà không thực sự trích xuất các tệp trong đó.
Dhwanil shah

Khi tôi thử openpyxl với cờ read_only, nó nhanh hơn đáng kể (nhanh hơn 200 lần cho tệp 5 MB của tôi). load_workbook(excel_file).sheetnamestrung bình 8,24 giây trong đó load_workbook(excel_file, read_only=True).sheetnamestrung bình 39,6ms.
flutefreak7

0
from openpyxl import load_workbook

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

Đối với tệp Excel 5 MB tôi đang làm việc, load_workbookkhông có read_onlycờ mất 8,24 giây. Với read_onlycờ chỉ mất 39,6 ms. Nếu bạn vẫn muốn sử dụng thư viện Excel và không thả vào giải pháp xml, thì nhanh hơn nhiều so với các phương pháp phân tích toàn bộ tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.