如何将OpenDocument电子表格转换为pandas DataFrame?

Lam*_*829 37 python opendocument dataframe libreoffice pandas

Python库可以读取Excel电子表格并将它们转换为pandas.DataFramewith pandas.read_excel(file)命令.在引擎盖下,它使用不支持 ods文件的xlrd库.

是否有相当于pandas.read_excelods文件?如果没有,我如何为Open Document Formatted电子表格(ods文件)做同样的事情?LibreOffice和OpenOffice使用ODF.

dav*_*tch 15

您可以.ods使用以下模块在Python中阅读ODF(Open Document Format )文档:

使用ezodf,一个简单的ODS-to-DataFrame转换器可能如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

PS

  • 已在pandas问题跟踪器上请求ODF电子表格(*.ods文件)支持:https://github.com/pydata/pandas/issues/2311,但仍未实现.

  • ezodf在未完成的PR9070中用于在熊猫中实现ODF支持.PR现已关闭(请阅读PR以进行技术讨论),但它仍然可用作 pandas分支中的实验性功能.

  • 还有一些强力方法直接从XML代码中读取(这里)


Max*_*axU 9

这是一个使用ezodf模块的快速而肮脏的黑客:

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()})
Run Code Online (Sandbox Code Playgroud)

测试:

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
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 所有其他有用的参数,如header,skiprows,index_col,parse_cols未在此功能中实现-如果你想实现他们随时更新这个问题
  • ezodf取决于lxml确保安装它

  • 我试过你的代码。它非常棒,除了它在数据帧末尾添加了两个“NaN”行。你有类似的经历吗? (2认同)

sky*_*don 6

pandas 现在支持 .ods 文件。您必须先安装odfpy模块。然后它将像普通的 .xls 文件一样工作。

conda install -c conda-forge odfpy
Run Code Online (Sandbox Code Playgroud)

然后

pd.read_excel('FILE_NAME.ods', engine='odf')
Run Code Online (Sandbox Code Playgroud)

  • 甚至只是 `df = pd.read_excel ('sample.ods')` (2认同)

CPB*_*PBL 5

编辑:令人高兴的是,如果您可以更新到最新的 Pandas 版本,下面的答案现在已经过时了。如果您仍想使用 Pandas 版本的数据,并仅在需要时从 ODS 更新数据,请继续阅读。


看来答案是否定的!我认为 ODS 中的读取工具仍然很简陋。如果您使用 POSIX,也许可以选择在使用 Pandas 非常好的 xlsx 导入工具之前即时导出到 xlsx 的策略:

unoconv -f xlsx -o tmp.xlsx myODSfile.ods 
Run Code Online (Sandbox Code Playgroud)

总而言之,我的代码如下所示:

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']
Run Code Online (Sandbox Code Playgroud)

这里的 fileOlderThan() 是一个函数(参见http://github.com/cpbl/cpblUtilities),如果 tmp.xlsx 不存在或早于 .ods 文件,则返回 true。


Wil*_*Ayd 5

这在0.25大熊猫中可用。只要您安装了odfpy,您就可以

pd.read_excel("the_document.ods", engine="odf")
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这个解决方案没有获得更高的票数。在使用 pandas 之前,您只需使用“pip install odfpy”安装 odfpy。 (4认同)
  • 在当前的 pandas 版本中,不需要定义“engine”;它会被自动检测到。`pd.read_excel("file.ods")` 就足够了。 (3认同)
  • 也可以使用 conda install odfpy 安装 (2认同)

Jan*_*cke -1

如果可能,从电子表格应用程序另存为 CSV,然后使用pandas.read_csv(). IIRC,一个“ods”电子表格文件,实际上是一个 XML 文件,其中还包含相当多的格式信息。因此,如果涉及表格数据,请首先将此原始数据提取到中间文件(在本例中为 CSV),然后您可以使用其他程序(例如 Python/pandas)对其进行解析。