我想根据特定条件从大型DataFrame生成分层的TFrecord文件,为此我使用write.partitionBy()
。我也在SPARK中使用tensorflow-connector,但这显然不能与write.partitionBy()
操作一起使用。因此,除了尝试分两个步骤工作外,我没有找到其他方法:
partitionBy()
根据我的条件对数据帧进行分区,并将生成的分区写入镶木地板文件中。这是我无法有效执行的第二步。我的想法是读取执行器上的各个拼花地板文件,然后立即将它们写入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文件,这对我没有帮助。
还有其他建议吗?
答案 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