パンダ:Excelファイルでシートのリストを検索する


144

新しいバージョンのPandasでは、次のインターフェイスを使用し Excelファイルを読み込みます。

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

しかし、利用可能なシートがわからない場合はどうなりますか?

たとえば、次のシートのExcelファイルを使用しています

データ1、データ2 ...、データN、foo、bar

わからない N先験的に。

パンダのExcelドキュメントからシートのリストを取得する方法はありますか?

回答:


253

ExcelFileクラス(およびsheet_names属性)は引き続き使用できます。

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

xl.sheet_names  # see all sheet names

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

その他のオプションについては、解析のドキュメントを参照してください...


1
@Andyに感謝します。PandasはExcelシートをロードしExcelFileますか?また、シートのリストを調べてN個をロードすることにしたとしたら、その時点read_excelで各シートを呼び出し(新しいインターフェイス)するx1.parseか、それとも続けるべきでしょうか。
Amelio Vazquez-Reina

2
ExcelFileがファイルを開いたままにしている(そしてそれをすべて読み取っていない)と思います。解析を使用する(そしてファイルを1回だけ開く)ことがここでは最も理にかなっていると思います。tbh read_excelの到着を逃した!
アンディヘイデン

6
ここで言及しましたが、私はDataFramesの辞書を使い続けるのが好きです{sheet_name: xl.parse(sheet_name) for sheet_name in xl.sheet_names}
Andy Hayden

2
私があなたにもっと賛成票を与えることができるといいのですが、これはパンダの複数のバージョンでも機能します!(なぜそう頻繁にAPIを変更するような知らない)ここでは、parse関数で私を指してくれてありがとうは、現在のリンクはかかわらず、次のとおりです。pandas.pydata.org/pandas-docs/stable/generated/...
エゼキエルKruglick

3
@NicholasLu反対投票は不要でした、この回答は2013年からです!とはいえ、ExcelFileはExcelファイルを解析する元の方法ですが、非推奨ではなく、完全に有効な方法です。
アンディヘイデン

37

2番目のパラメーター(シート名)を明示的にNoneとして指定する必要があります。このような:

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

「df」はすべてDataFrameのディクショナリとしてのシートです。次のコマンドを実行して確認できます。

df.keys()

このような結果:

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

詳細については、パンダのドキュメントを参照してください:https : //pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html


3
これにより、不要なすべてのシートがDataFrameとして解析されます。「xls / xlsxファイルの読み方」は別の質問です。
アンディヘイデン

7
@AndyHaydenそれは効率的ではないかもしれませんが、すべてのシートを気にする場合、または追加のオーバーヘッドを気にしない場合は、最良の場合があります。
CodeMonkey 2017

8

これは、@ divingTobiの回答に触発された、私が見つけた最速の方法です。すべてxlrd、openpyxl、またはpandasに基づく回答は、最初にファイル全体をロードするため、時間がかかります。

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の答えを基にして、ファイル全体を抽出する必要はありません。とzf.openzipファイルから直接読み取ることが可能です。

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

2連続 readlineは醜いですが、コンテンツはテキストの2行目にのみあります。ファイル全体を解析する必要はありません。

このソリューションは、read_excelバージョンよりもはるかに高速であるように思われ、おそらく完全抽出バージョンよりも高速です。


いいえ、.xlsは完全に異なるファイル形式なので、このコードが機能するとは思いません。
divingTobi

2

私はxlrd、pandas、openpyxlなどのライブラリを試してみましたが、ファイル全体を読み取るときにファイルサイズが大きくなると、それらすべてに指数関数的な時間がかかるようです。上記で「オンデマンド」を使用した他のソリューションは、私にはうまくいきませんでした。最初にシート名を取得するだけの場合、次の関数は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

すべてのxlsxは基本的にzipファイルであるため、基になるxmlデータを抽出し、ライブラリー関数と比較してほんの一瞬でワークブックからシート名を直接読み取ります。

ベンチマーク:(4シートの6mb xlsxファイル)
Pandas、xlrd: 12秒
openpyxl: 24秒
提案された方法: 0.4秒

私の要件はシート名を読むことだけだったので、全体の時間を読むことの不必要なオーバーヘッドが私を悩ませていたので、代わりにこのルートをとりました。


使用しているモジュールは何ですか?
ダニエル

@Daniel zipfile組み込みモジュールでxmltodictあり、XMLを簡単に反復可能な辞書に変換するために使用したモジュールのみを使用しました。以下の@divingTobiの回答を見ると、実際にファイルを抽出せずに同じファイルを読み取ることができます。
Dhwanil shah

readpyフラグを指定してopenpyxlを試したところ、大幅に高速になりました(5 MBのファイルで200倍高速)。load_workbook(excel_file).sheetnames平均8.24秒、load_workbook(excel_file, read_only=True).sheetnames平均39.6ミリ秒。
flutefreak7

0
from openpyxl import load_workbook

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

フラグload_workbookなしで使用している5MBのExcelファイルの場合、read_only8.24秒かかりました。read_onlyフラグがあれば、39.6ミリ秒しかかかりませんでした。それでもExcelライブラリを使用し、xmlソリューションにドロップしない場合は、ファイル全体を解析するメソッドよりもはるかに高速です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.