如何使用SPARK将多个实木复合地板文件转换为TFrecord文件?

时间:2019-01-22 16:13:29

标签: apache-spark pyspark pyspark-sql parquet tfrecord

我想根据特定条件从大型DataFrame生成分层的TFrecord文件,为此我使用write.partitionBy()。我也在SPARK中使用tensorflow-connector,但这显然不能与write.partitionBy()操作一起使用。因此,除了尝试分两个步骤工作外,我没有找到其他方法:

  1. 使用partitionBy()根据我的条件对数据帧进行分区,并将生成的分区写入镶木地板文件中。
  2. 使用tensorflow-connector插件读取这些实木复合地板文件以将其转换为TFrecord文件。

这是我无法有效执行的第二步。我的想法是读取执行器上的各个拼花地板文件,然后立即将它们写入TFrecord文件。但这需要访问SQLContext,这只能在驱动程序(discussed here)中进行,而不能并行进行。我想做这样的事情:

# List all parquet files to be converted
import glob, os
files = glob.glob('/path/*.parquet'))

sc = SparkSession.builder.getOrCreate()
sc.parallelize(files, 2).foreach(lambda parquetFile: convert_parquet_to_tfrecord(parquetFile))

我可以构造函数convert_parquet_to_tfrecord以便能够在执行程序上执行此操作吗?

我还尝试在读取所有实木复合地板文件时仅使用通配符:

SQLContext(sc).read.parquet('/path/*.parquet')

这确实读取了所有实木复合地板文件,但不幸的是没有读取到单个分区中。似乎原始结构丢失了,所以如果我想将各个实木复合地板文件的确切内容转换为TFrecord文件,这对我没有帮助。

还有其他建议吗?

2 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,则希望将分区本地写入工作人员磁盘。

如果是这种情况,那么我建议您查看spark-tensorflow-connector's的使用说明。

这是您要查找的代码(如上面链接的文档中所述):

.expect()

另一方面,如果您担心效率问题,为什么要使用pyspark?最好改用scala。

答案 1 :(得分:0)

尝试spark-tfrecord。

Spark-TFRecord是一个类似于spark-tensorflow-connector的工具,但是它具有partitionBy。以下示例显示了如何对数据集进行分区。

import org.apache.spark.sql.SaveMode

// create a dataframe

val df = Seq((8, "bat"),(8, "abc"), (1, "xyz"), (2, "aaa")).toDF("number", "word")
val tf_output_dir = "/tmp/tfrecord-test"

// dump the tfrecords to files.
df.repartition(3, col("number")).write.mode(SaveMode.Overwrite).partitionBy("number").format("tfrecord").option("recordType", "Example").save(tf_output_dir)

更多信息,请参见 Github仓库: https://github.com/linkedin/spark-tfrecord