Hoe converteer ik OpenDocument-spreadsheets naar een pandas DataFrame?

De Python-bibliotheek kan Excel-spreadsheets lezen en converteer ze naar een pandas.DataFramemet de opdracht pandas.read_excel(file). Onder de motorkap gebruikt het een xlrd-bibliotheek die ondersteunt geenods-bestanden.

Is er een equivalent van pandas.read_excelvoor ods-bestanden? Zo niet, hoe kan ik dan hetzelfde doen voor een spreadsheet met open documentindeling (ods-bestand)? ODF wordt gebruikt door LibreOffice en OpenOffice.


Antwoord 1, autoriteit 100%

Dit is standaard beschikbaar in panda’s 0.25. Zolang je odfpyhebt geïnstalleerd (conda install odfpyOF pip install odfpy), kun je

pd.read_excel("the_document.ods", engine="odf")

Antwoord 2, autoriteit 27%

Je kunt ODF-documenten (Open Document Format .ods) lezen in Python met behulp van de volgende modules:

Met ezodf kan een eenvoudige ODS-naar-DataFrame-converter er als volgt uitzien:

import pandas as pd
import ezodf
doc = ezodf.opendoc('some_odf_spreadsheet.ods')
print("Spreadsheet contains %d sheet(s)." % len(doc.sheets))
for sheet in doc.sheets:
    print("-"*40)
    print("   Sheet name : '%s'" % sheet.name)
    print("Size of Sheet : (rows=%d, cols=%d)" % (sheet.nrows(), sheet.ncols()) )
# convert the first sheet to a pandas.DataFrame
sheet = doc.sheets[0]
df_dict = {}
for i, row in enumerate(sheet.rows()):
    # row is a list of cells
    # assume the header is on the first row
    if i == 0:
        # columns as lists in a dictionary
        df_dict = {cell.value:[] for cell in row}
        # create index for the column headers
        col_index = {j:cell.value for j, cell in enumerate(row)}
        continue
    for j, cell in enumerate(row):
        # use header instead of column index
        df_dict[col_index[j]].append(cell.value)
# and convert to a DataFrame
df = pd.DataFrame(df_dict)

P.S.

  • ODF-spreadsheet (*.ods-bestanden) ondersteuning is aangevraagd voor de pandasissue tracker: https://github.com/pydata/pandas/issues/2311, maar het is nog steeds niet geïmplementeerd.

  • ezodfwerd gebruikt in de onvoltooide PR9070om ODF-ondersteuning in panda’s te implementeren. Die PR is nu gesloten (lees de PR voor een technische discussie), maar het is nog steeds beschikbaar als een experimentele functie in dezepandasvork.

  • er zijn ook enkele brute force-methoden om rechtstreeks uit de XML-code te lezen (hier)

Antwoord 3, autoriteit 17%

Hier is een snelle en vuile hack die de ezodf-module gebruikt:

import pandas as pd
import ezodf
def read_ods(filename, sheet_no=0, header=0):
    tab = ezodf.opendoc(filename=filename).sheets[sheet_no]
    return pd.DataFrame({col[header].value:[x.value for x in col[header+1:]]
                         for col in tab.columns()})

Testen:

In [92]: df = read_ods(filename='fn.ods')
In [93]: df
Out[93]:
     a    b    c
0  1.0  2.0  3.0
1  4.0  5.0  6.0
2  7.0  8.0  9.0

OPMERKINGEN:

  • alle andere nuttige parameters zoals header, skiprows, index_col, parse_colszijn NIET geïmplementeerd in deze functie – voel je vrij om deze vraag bij te werken als je ze wilt implementeren
  • ezodfhangt af van lxmlzorg ervoor dat je het hebt geïnstalleerd

Antwoord 4, autoriteit 8%

Bewerken: Gelukkig is dit antwoord hieronder nu verouderd, als je kunt updaten naar een recente Pandas-versie.
Als u nog steeds met een Pandas-versie van uw gegevens wilt werken en deze alleen vanuit ODS wilt bijwerken wanneer dat nodig is, lees dan verder.


Het lijkt erop dat het antwoord Nee is!
En ik zou de tools om te lezen in ODS nog steeds haveloos karakteriseren.
Als je POSIX gebruikt, is de strategie om on-the-fly naar xlsx te exporteren voordat je Pandas’ zeer mooie importtools voor xlsx gebruikt misschien een optie:

unoconv -f xlsx -o tmp.xlsx myODSfile.ods 

In totaal ziet mijn code er als volgt uit:

import pandas as pd
import os
if fileOlderThan('tmp.xlsx','myODSfile.ods'):
    os.system('unoconv -f xlsx -o tmp.xlsx myODSfile.ods ')
xl_file = pd.ExcelFile('tmp.xlsx')
dfs = {sheet_name: xl_file.parse(sheet_name) 
          for sheet_name in xl_file.sheet_names}
df=dfs['Sheet1']

Hier is fileOlderThan() een functie (zie http://github.com/cpbl/cpblUtilities) die true retourneert als tmp.xlsx niet bestaat of ouder is dan het .ods-bestand.


Antwoord 5, autoriteit 5%

Een andere optie: read-ods-with-odfpy. Deze module neemt een OpenDocument-spreadsheet als invoer en retourneert een lijst waaruit een DataFrame kan worden gemaakt.


Antwoord 6, autoriteit 5%

Als je maar een paar .ods-bestanden hebt om te lezen, zou ik het gewoon openen in openoffice en het opslaan als een Excel-bestand. Als je veel bestanden hebt, kun je de unoconv-opdrachtin Linux om de .ods-bestanden programmatisch naar .xls te converteren (met bash)

Dan is het heel gemakkelijk om het in te lezen met pd.read_excel('filename.xls')


Antwoord 7, autoriteit 5%

pandas ondersteunt nu .ods-bestanden. u moet eerst de odfpy-module installeren. dan zal het werken als een normaal .xls-bestand.

conda install -c conda-forge odfpyr

dan

pd.read_excel('FILE_NAME.ods', engine='odf')

Antwoord 8, autoriteit 3%

Ik heb veel geluk gehad met panda’s read_clipboard.
Cellen selecteren en vervolgens kopiëren vanuit Excel of opendocument.
Voer in python het volgende uit.

import pandas as pd
data = pd.read_clipboard()

Panda’s zullen het goed doen op basis van de gekopieerde cellen.


Antwoord 9, autoriteit 3%

Sommige reacties hebben erop gewezen dat odfpy of andere externe pakketten nodig zijn om deze functionaliteit te krijgen, maar houd er rekening mee dat in recente versies van Pandas (huidig ​​is 1.1, augustus-2020) er ondersteuning is voor het ODS-formaat in functies zoals pd.ExcelWriter () en pd.read_excel(). U hoeft alleen de juiste engine “odf” op te geven om te kunnen werken met OpenDocument-bestandsindelingen (.odf, .ods, .odt).


Antwoord 10, autoriteit 2%

Sterk gebaseerd op het antwoord van davidovitch (dank u), heb ik een pakketsamengesteld dat leest in een .ods-bestand en retourneert een DataFrame. Het is geen volledige implementatie in pandaszelf, zoals zijn PR, maar het biedt een eenvoudige read_ods-functie die het werk doet.

Je kunt het installeren met pip install pandas_ods_reader. Het is ook mogelijk om aan te geven of het bestand een koprij bevat of niet, en om aangepaste kolomnamen op te geven.


Antwoord 11

Sla indien mogelijk op als CSV vanuit de spreadsheettoepassing en gebruik vervolgens pandas.read_csv(). IIRC, een ‘ods’-spreadsheetbestand is eigenlijk een XML-bestand dat ook behoorlijk wat opmaakinformatie bevat. Dus als het om tabelgegevens gaat, extraheer deze onbewerkte gegevens dan eerst naar een tussenbestand (in dit geval CSV), dat je vervolgens kunt ontleden met andere programma’s, zoals Python/panda’s.


Antwoord 12

Er is ondersteuning voor het lezen van Excel-bestanden in Pandas (zowel xls als xlsx), zie de read_excelcommando. U kunt OpenOffice gebruiken om de spreadsheet op te slaan als xlsx. De conversie kan ook automatisch worden gedaan op de opdrachtregel, blijkbaar met behulp van de converteren naar opdrachtregelparameter.

Het lezen van de gegevens van xlsx vermijdt een aantal problemen (datumnotaties, getalnotaties, unicode) die u tegen kunt komen wanneer u eerst naar CSV converteert.

Other episodes