【问题标题】:Pandas: Write to Excel not working in DatabricksPandas:写入 Excel 在 Databricks 中不起作用
【发布时间】:2021-09-28 19:50:03
【问题描述】:

我试图将 parquet 文件转换为 excel 文件。但是,当我尝试这样做时,使用 pandas 或 openpyxl 引擎,它显示“Operation not supported”错误。但是,我可以在 databricks 中使用 openpyxl 引擎读取 excel 文件。

在阅读以下代码时:

xlfile = '/dbfs/mnt/raw/BOMFILE.xlsx'
tmp_csv = '/dbfs/mnt/trusted/BOMFILE.csv'
pdf = pd.DataFrame(pd.read_excel(xlfile, engine='openpyxl'))
pdf.to_csv (tmp_csv, index = None, header=True)

但是,当我尝试使用 openpyxl 和 xlswriter 编写相同的内容时,它不起作用:

parq = '/mnt/raw/PRODUCT.parquet'
final = '/dbfs/mnt/trusted/PRODUCT.xlsx'
df = spark.read.format("parquet").option("header", "true").load(parq)
pandas_df = df.toPandas()
pandas_df.to_excel(final, engine='openpyxl')
#pandas_df.to_excel(outfile, engine='xlsxwriter')#, sheet_name=tbl)

我遇到的错误:

FileCreateError: [Errno 95] Operation not supported

OSError: [Errno 95] Operation not supported
During handling of the above exception, another exception occurred:
FileCreateError                           Traceback (most recent call last)
<command-473603709964454> in <module>
     17       final = '/dbfs/mnt/trusted/PRODUCT.xlsx'
     18       print(outfile)
---> 19       pandas_df.to_excel(outfile, engine='openpyxl')
     20       #pandas_df.to_excel(outfile, engine='xlsxwriter')#, sheet_name=tbl)

/databricks/python/lib/python3.7/site-packages/pandas/core/generic.py in to_excel(self, excel_writer, sheet_name, na_rep, float_format, columns, header, index, index_label, startrow, startcol, engine, merge_cells, encoding, inf_rep, verbose, freeze_panes)
   2179             startcol=startcol,
   2180             freeze_panes=freeze_panes,
-> 2181             engine=engine,
   2182         )
   2183 

请提出建议。

【问题讨论】:

    标签: python pandas databricks azure-databricks xlsxwriter


    【解决方案1】:

    问题在于,当涉及到 DBFS 中的本地文件 API 支持时,存在 limitations/dbfs 熔断器)。例如,它不支持 Excel 文件所需的随机写入。来自文档:

    不支持随机写入。对于需要随机写入的工作负载,请先在本地磁盘上执行 I/O,然后将结果复制到 /dbfs。

    你的情况可能是:

    from shutil import copyfile
    
    parq = '/mnt/raw/PRODUCT.parquet'
    final = '/dbfs/mnt/trusted/PRODUCT.xlsx'
    temp_file = '/tmp/PRODUCT.xlsx'
    df = spark.read.format("parquet").option("header", "true").load(parq)
    pandas_df = df.toPandas()
    pandas_df.to_excel(temp_file, engine='openpyxl')
    
    copyfile(temp_file, final)
    

    附:您还可以使用 dbutils.fs.cp 复制文件 (doc) - 它也适用于不支持 /dbfs 的社区版

    【讨论】:

    • 谢谢。这也出现在 XlsxWriter issues 中。你知道这些文档中的“随机写入”是什么意思吗?
    • 随机意味着数据不是按顺序写入的。例如,我们写了一些字节,然后倒退到更早的位置并写了新的字节。对于 excel,这是很常见的模式
    • 谢谢。这应该很明显,但我不确定这是否是什么意思,因为 XlsxWriter 不使用任何随机写入(尽管它确实使用带有 rewind() 的随机读取)。我想问题出在 zipfile.py 上,它可能确实有随机写入。上面没有显示完整的堆栈跟踪,但在我链接到异常的问题中,在文件 seek() 周围的 zipfile.py 中抛出了异常。无论如何感谢您的链接。很高兴知道该解决方法已正式记录。
    • 是的,写zipfile通常需要随机查找,因为你需要在写完数据后更新一些偏移量。可以一次性完成,但它是特定于用例的
    猜你喜欢
    • 2022-08-05
    • 2013-08-09
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2017-11-26
    • 1970-01-01
    相关资源
    最近更新 更多