web-dev-qa-db-fra.com

Pandas: recherche de la liste des feuilles dans un fichier Excel

La nouvelle version de Pandas utilise l'interface suivante pour charger des fichiers Excel:

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

mais si je ne connais pas les feuilles disponibles?

Par exemple, je travaille avec des fichiers Excel que les feuilles suivantes

Données 1, Données 2 ..., Données N, toto, bar

mais je ne sais pas N a priori.

Existe-t-il un moyen d'obtenir la liste des feuilles d'un document Excel dans les pandas?

94

Vous pouvez toujours utiliser la classe ExcelFile (et le sheet_names attribut):

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

xl.sheet_names  # see all sheet names

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

voir docs for parse pour plus d'options ...

167
Andy Hayden

Vous devez explicitement spécifier le deuxième paramètre (nom de la feuille) en tant que Aucun. comme ça:

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

"df" sont toutes des feuilles sous forme de dictionnaire de DataFrames, vous pouvez le vérifier en exécutant ceci:

df.keys()

résultat comme ceci:

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

veuillez consulter pandas doc pour plus de détails: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_Excel.html

25
Nicholas Lu

En vous appuyant sur la réponse de @dhwanil_shah, vous n'avez pas besoin d'extraire l'intégralité du fichier. Avec zf.open il est possible de lire directement à partir d’un fichier compressé.

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

Les deux readlines consécutifs sont laids, mais le contenu ne figure que dans la deuxième ligne du texte. Pas besoin d'analyser le fichier entier.

Cette solution semble être beaucoup plus rapide que le read_Excel version, et probablement aussi plus rapide que la version d'extrait complet.

1
divingTobi

J'ai essayé xlrd, pandas, openpyxl et d'autres bibliothèques similaires, et toutes semblent prendre un temps exponentiel à mesure que la taille du fichier augmente, à mesure qu'il lit l'intégralité du fichier. Les autres solutions mentionnées ci-dessus où ils utilisaient 'on_demand' ne fonctionnaient pas pour moi. Si vous voulez juste obtenir les noms de feuilles au départ, la fonction suivante fonctionne pour les fichiers 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

Étant donné que tous les xlsx sont essentiellement des fichiers compressés, nous extrayons les données xml sous-jacentes et lisons directement les noms des feuilles dans le classeur, ce qui prend une fraction de seconde par rapport aux fonctions de la bibliothèque.

Analyse comparative: (sur un fichier xlsx de 6 Mo avec 4 feuilles)
Pandas, xlrd: 12 secondes
openpyxl: 24 secondes
Méthode proposée: 0.4 secondes

Puisque mon exigence consistait simplement à lire les noms des feuilles, la surcharge inutile de lire tout le temps me causait des problèmes, alors j’ai pris cette voie à la place.

0
Dhwanil shah