【问题标题】:How to read files written by Spark with pandas?如何用 pandas 读取 Spark 编写的文件?
【发布时间】:2019-12-14 15:19:37
【问题描述】:

当 Spark 将日期帧数据写入 parquet 文件时,Spark 将创建一个目录,其中包含多个单独的 parquet 文件。保存代码:

term_freq_df.write
            .mode("overwrite")
            .option("header", "true")
            .parquet("dir/to/save/to")

我需要用 pandas 从这个目录中读取数据:

term_freq_df = pd.read_parquet("dir/to/save/to") 

错误:

IsADirectoryError: [Errno 21] Is a directory: 

如何通过两个代码示例使用相同文件路径的简单方法解决此问题?

【问题讨论】:

  • 你用的是什么版本的熊猫?你能显示完整的错误回溯吗?

标签: python pandas apache-spark parquet


【解决方案1】:

如您所述,保存 Spark 时会在一个目录中创建多个 parquet 文件。要使用 pandas 读取这些文件,您可以分别读取这些文件,然后将结果连接起来。

import glob
import os
import pandas as pd

path = "dir/to/save/to"
parquet_files = glob.glob(os.path.join(path, "*.parquet"))
df = pd.concat((pd.read_parquet(f) for f in parquet_files))

【讨论】:

  • 错误是 RuntimeError: Decompression 'SNAPPY' not available。选项:['GZIP', 'UNCOMPRESSED'],所以改为 csv 格式。这是有效的,谢谢
【解决方案2】:

通常,pandas.read_parquet 可以处理读取多个(分区)parquet 文件的目录。所以我很想看看你得到的完整错误回溯。

演示这个工作正常:

In [82]: pd.__version__ 
Out[82]: '0.25.0'

In [83]: df = pd.DataFrame({'A': ['a', 'b']*2, 'B':[1, 2, 3, 4]})

In [85]: df.to_parquet("test_directory", partition_cols=['A'])

这创建了一个包含多个 parquet 文件的“test_directory”文件夹。我可以使用 pandas 读回这些内容:

In [87]: pd.read_parquet("test_directory/")
Out[87]: 
   B  A
0  1  a
1  3  a
2  2  b
3  4  b

【讨论】:

  • 我的熊猫版本是 0.23.4。我尝试在更新到 0.25.0 后运行您的代码,直到出现错误:RuntimeError: Compression 'snappy' not available。选项:['GZIP', '未压缩']
  • 好的,但这是与目录问题无关的错误(您在原始问题中引用了不同的错误)。这来自使用fastparquet 引擎编写镶木地板文件。您可以将compression='GZIP' 传递给to_parquet 以避免此错误。
  • 请注意,这种情况下的多个文件是由于使用了 Spark。 Spark 在保存时会将每个数据分区(默认为 200)保存为单独的文件。我不确定 pandas 是否可以处理这个问题(我实际上并没有尝试过),这就是我在上面给出答案的原因。
  • 是的,pandas(引擎盖下带有 pyarrow 或 fastparquet)通常应该能很好地处理这个问题。如果有特定的情况不起作用,这是一个错误,欢迎报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2023-03-16
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多