2013-07-24 25 views
23

La libreria Python può leggere fogli di calcolo Excel e convertirli in un pandas.DataFrame con il comando pandas.read_excel(file). Sotto il cofano, utilizza la libreria xlrd che contiene i file does not support ods.Come convertire i fogli di calcolo di OpenDocument in un DataFrame panda?

Esiste un equivalente di pandas.read_excel per i file ods? In caso contrario, come posso fare lo stesso per un foglio di calcolo formattato Open Document (file ods)? ODF è usato da LibreOffice e OpenOffice.

risposta

1

Se possibile, salvare come CSV dall'applicazione foglio di calcolo e quindi utilizzare pandas.read_csv(). IIRC, un file di foglio di calcolo "ods" è in realtà un file XML che contiene anche alcune informazioni di formattazione. Quindi, se si tratta di dati tabulari, estrai questi dati grezzi prima in un file intermedio (CSV, in questo caso), che puoi quindi analizzare con altri programmi, come Python/panda.

+0

Grazie. Sarebbe bello se ci fosse qualcosa di più diretto, ma immagino che questa sia una possibilità. – Lamps1829

+0

Non c'è niente di più diretto di un file che contiene solo i dati grezzi. Tali file devono essere in un determinato formato di file. Esistono formati binari per questo (come NetCDF o HDF5) e formati ascii, come CSV. Sfortunatamente, CSV non è un vero standard. Tuttavia, CSV è piuttosto semplice da affrontare nella maggior parte delle situazioni. –

3

Un'altra opzione: read-ods-with-odfpy. Questo modulo prende un foglio di calcolo di OpenDocument come input e restituisce un elenco dal quale è possibile creare un DataFrame.

1

È disponibile il supporto per la lettura dei file Excel in Panda (sia xls che xlsx), vedere il comando read_excel. È possibile utilizzare OpenOffice per salvare il foglio di calcolo come xlsx. La conversione può anche essere eseguita automaticamente sulla riga di comando, apparentemente, usando convert-to command line parameter.

La lettura dei dati da xlsx evita alcuni dei problemi (formati data, formati numerici, unicode) che è possibile incontrare quando si converte in CSV.

1

Sembra che la risposta sia No! E vorrei caratterizzare gli strumenti da leggere in ODS ancora laceri. Se siete su POSIX, forse la strategia di esportare in xlsx al volo prima di utilizzare strumenti molto bello importatori Panda per xlsx è un'opzione:

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

Complessivamente, il mio codice è simile:

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

Qui fileOlderThan() è una funzione (vedere http://github.com/cpbl/cpblUtilities) che restituisce true se tmp.xlsx non esiste o è più vecchio del file .ods.

8

Si può leggere ODF (Open Document Format) di documenti in Python utilizzando i seguenti moduli:

Utilizzando ezodf, un semplice ODS-to -DataFrame convertitore potrebbe assomigliare a questo:

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) 

Il foglio di calcolo ODF (file * .ods) è stato richiesto sul tracker di emissione pandas: https://github.com/pydata/pandas/issues/2311, ma non è ancora implementato.

ezodf è stato utilizzato nello PR9070 incompleto per implementare il supporto ODF nei panda. Quella PR è ora chiusa (leggi il PR per una discussione tecnica), ma è ancora disponibile come funzionalità sperimentale nella forcella thispandas.

+0

Funziona molto bene. Dovresti fornire qualcosa di simile a un pacchetto esterno (che dipende sia da 'ezodf' che' pandas') in modo che gli utenti possano finalmente avere una funzione read_ods()! – Antonello

1

Ecco un hack rapido e sporco che utilizza ezodf modulo:

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()}) 

prova:

In [92]: df = read_ods(filename=fn) 

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 

NOTA: tutti gli altri parametri utili come header, skiprows, index_col, parse_cols sono non implementato in questa funzione - sentiti libero di aggiornare questa domanda se vuoi implementarli

0

Se si hanno solo alcuni file .ods da leggere, lo aprirò semplicemente in openoffice e lo salverò come un file excel. Se si dispone di un sacco di file, è possibile utilizzare il unoconv command in Linux per convertire i file .ods per .xls di programmazione (with bash)

allora è davvero facile da leggere con pd.read_excel('filename.xls')