【问题标题】:How to convert OpenDocument spreadsheets to a pandas DataFrame?如何将 OpenDocument 电子表格转换为 pandas DataFrame?
【发布时间】:2013-07-23 23:41:22
【问题描述】:

Python 库 可以读取 Excel 电子表格并使用 pandas.read_excel(file) 命令将其转换为 pandas.DataFrame。在底层,它使用xlrd 库,其中does not support ods 文件。

对于 ods 文件,是否有相当于 pandas.read_excel 的内容?如果没有,我该如何对 Open Document Formatted 电子表格(ods 文件)执行相同的操作? ODF 被 LibreOffice 和 OpenOffice 使用。

【问题讨论】:

  • 自 2012 年以来,pandas github 上有一个功能请求here。我不知道他们为什么还没有实现它!
  • 自 2019 年 8 月起实施 :)
  • 票数最高的答案完美解决了问题。也许你应该接受它?

标签: pandas python pandas libreoffice dataframe opendocument


【解决方案1】:

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

conda install -c conda-forge odfpyr

那么

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

【讨论】:

  • 甚至只是df = pd.read_excel ('sample.ods')
【解决方案2】:

一些回复指出需要 odfpy 或其他外部包来获得此功能,但请注意,在最新版本的 Pandas(当前为 1.1,2020 年 8 月)中,在 pd.ExcelWriter 等函数中支持 ODS 格式() 和 pd.read_excel()。您只需要指定合适的引擎“odf”即可使用 OpenDocument 文件格式(.odf、.ods、.odt)。

【讨论】:

    【解决方案3】:

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


    似乎答案是否定的! 我会描述在 ODS 中阅读的工具仍然参差不齐。 如果您使用的是 POSIX,也许在使用 Pandas 非常好的 xlsx 导入工具之前即时导出到 xlsx 的策略是一种选择:

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

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

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

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

    【讨论】:

      【解决方案4】:

      这在 pandas 0.25 中原生可用。只要您安装了 odfpyconda install odfpypip install odfpy),您就可以这样做

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

      【讨论】:

      • 不知道为什么这个解决方案没有更高的票数。在使用 pandas 之前,您只需要使用 pip install odfpy 安装 odfpy。
      • 使用pip install odfpy 安装它结果是 ImportError: Missing optional dependency 'odf'。使用 pip 或 conda 安装 odf。 Conda 没有这个包。我认为问题在于该包使用的是 Python 2.7,它已接近生命周期的尽头。
      • 也可以用conda install odfpy安装
      • pip install odfpy 之后这对我很有用。是否需要单独的引擎来回写该 Calc 电子表格?
      • 在最新的pandas版本中,不需要定义engine;它会被自动检测到。 pd.read_excel("file.ods") 就够了。
      【解决方案5】:

      根据 davidovitch 的回答(谢谢),我整理了一个 package,它读取 .ods 文件并返回一个 DataFrame。它不是 pandas 本身的完整实现,例如他的 PR,但它提供了一个简单的 read_ods 函数来完成这项工作。

      您可以使用pip install pandas_ods_reader 安装它。也可以指定文件是否包含标题行,并指定自定义列名。

      【讨论】:

        【解决方案6】:

        我在 pandas read_clipboard 上运气不错。 选择单元格,然后从 excel 或 opendocument 复制。 在 python 中运行以下命令。

        import pandas as pd
        data = pd.read_clipboard()
        

        Pandas 会根据复制的单元格做好工作。

        【讨论】:

          【解决方案7】:

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

          使用 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)
          

          附言

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

          • ezodf 在未完成的PR9070 中使用,以在 pandas 中实现 ODF 支持。该 PR 现已关闭(请阅读 PR 以进行技术讨论),但它仍可作为 thispandas fork 中的实验性功能使用。

          • 还有一些蛮力方法可以直接从 XML 代码中读取 (here)

          【讨论】:

          • 效果很好。您应该提供这样的东西作为外部包(取决于ezodfpandas),以便用户最终可以拥有 read_ods() 函数!
          • 使用此代码 python 在第 37 行返回错误 ValueError: arrays must all be same length df = pd.DataFrame(df_dict)
          • 我想您的电子表格已合并导致此错误的单元格。
          • @Ossarotte,我遇到了同样的错误。原来这是因为两个标题列具有相同的名称(所以它计算了两次行)。我重命名了其中一列,错误消失了,列行长度都一样。
          • @BringBackCommodore64 坦克。
          【解决方案8】:

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

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

          测试:

          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
          

          注意事项:

          • 所有其他有用的参数,如headerskiprowsindex_colparse_cols,都没有在这个函数中实现 - 如果你想实现它们,请随时更新这个问题
          • ezodf 取决于 lxml 确保已安装它

          【讨论】:

          • 我试过你的代码。太棒了,除了它在数据帧的末尾添加了两个NaN 行。你有过类似的经历吗?
          【解决方案9】:

          如果您只有几个 .ods 文件要阅读,我会在 openoffice 中打开它并将其保存为 excel 文件。如果您有很多文件,您可以在 Linux 中使用 unoconv command 以编程方式将 .ods 文件转换为 .xls (with bash)

          那么用pd.read_excel('filename.xls')阅读它真的很容易

          【讨论】:

            【解决方案10】:

            另一个选项:read-ods-with-odfpy。该模块将 OpenDocument 电子表格作为输入,并返回一个列表,从中可以创建一个 DataFrame。

            【讨论】:

              【解决方案11】:

              支持在 Pandas 中读取 Excel 文件(xls 和 xlsx),请参阅read_excel 命令。您可以使用 OpenOffice 将电子表格保存为 xlsx。转换也可以在命令行上自动完成,显然,使用convert-to command line parameter

              从 xlsx 读取数据可以避免在首先转换为 CSV 时可能遇到的一些问题(日期格式、数字格式、unicode)。

              【讨论】:

                【解决方案12】:

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

                【讨论】:

                • 谢谢。如果有更直接的东西会很好,但我想这是一种可能性。
                • 没有什么比只包含原始数据的文件更直接的了。此类文件必须采用某种文件格式。有二进制格式(如 NetCDF 或 HDF5)和 ascii 格式,如 CSV。不幸的是,CSV 并不是真正的标准。不过,在大多数情况下,CSV 处理起来非常简单。
                • 如果您修改 .ods 更新 .csv 会很好,但这可能已经超出了答案的范围......
                猜你喜欢
                • 1970-01-01
                • 2014-01-25
                • 2021-07-31
                • 2022-01-23
                • 1970-01-01
                • 2017-01-08
                • 1970-01-01
                • 2012-10-07
                • 1970-01-01
                相关资源
                最近更新 更多