【发布时间】:2018-05-03 17:31:53
【问题描述】:
我正在使用 pandas 和 spark 数据框。数据帧总是非常大(> 20 GB),标准的火花函数不足以满足这些大小。目前我正在将我的熊猫数据框转换为像这样的火花数据框:
dataframe = spark.createDataFrame(pandas_dataframe)
我进行这种转换是因为使用 spark 将数据帧写入 hdfs 非常容易:
dataframe.write.parquet(output_uri, mode="overwrite", compression="snappy")
但是对于大于 2 GB 的数据帧,转换失败。 如果我将 spark 数据框转换为 pandas,我可以使用 pyarrow:
// temporary write spark dataframe to hdfs
dataframe.write.parquet(path, mode="overwrite", compression="snappy")
// open hdfs connection using pyarrow (pa)
hdfs = pa.hdfs.connect("default", 0)
// read parquet (pyarrow.parquet (pq))
parquet = pq.ParquetDataset(path_hdfs, filesystem=hdfs)
table = parquet.read(nthreads=4)
// transform table to pandas
pandas = table.to_pandas(nthreads=4)
// delete temp files
hdfs.delete(path, recursive=True)
这是从 spark 到 pandas 的快速转换,它也适用于大于 2 GB 的数据帧。我还没有找到相反的方法。意味着有一个熊猫数据框,我在 pyarrow 的帮助下将其转换为火花。问题是我真的找不到如何将 pandas 数据帧写入 hdfs。
我的熊猫版本:0.19.0
【问题讨论】:
-
您遇到什么错误?您确定应用程序在写入失败或之前(在数据帧转换期间)失败了吗?
-
由于 java 堆空间有限并且 createDataFrame 方法正在 java 堆上构建字节数组,因此失败并出现内存不足异常。为了解决这个问题,我们需要 pyarrow 解决方案。如前所述,它已经完美地适用于大熊猫的火花。但我也需要 pandas 来激发火花,因为我找不到将 pandas 直接保存到 hdfs 或 hive 的方法。
-
只是好奇——在这种大小下,为什么不直接将数据写入数据库呢?以 Postgres 为例,如果您仍想编写 Python 或 C 代码在数据库中对其进行操作。
-
一个 hack 可能是从大的创建 N 个 pandas 数据帧(每个小于 2 GB)(水平分区)并创建 N 个不同的 spark 数据帧,然后合并(联合)它们以创建最后一个写入 HDFS。我假设你的主机很强大,但你也有一个运行 Spark 的集群。
标签: python pandas apache-spark pyarrow apache-arrow