Pyspark - 如何将动作输出存储到RDD中

时间:2018-04-18 10:14:25

标签: apache-spark pyspark

我试图将reduce()的输出存储到RDD中,因此我可以在其上应用更多转换。

我在这里尝试过:

我有一个这样的文本文件:

hello
i'm Arya
i'm 21 yrold

Hello
i'm Jack
i'm 30.

i am ali.

i'm Harry
I'am 40 years old
and i am an engineer.

我想合并每一行而不是段落。

rdd = sc.textFile('asd.txt')
rdd1=sc.parallelize([rdd.reduce(lambda x,y: "\n".join([x,y]))])

这有效,但应该有更有效的方法。我不想每次都创建另一个rdd。

2 个答案:

答案 0 :(得分:1)

我相信这个问题应该得到更详细的回答。让我们从这段代码开始:

rdd.reduce(lambda x,y: "\n".join([x,y]))

与您的想法相反,它并不保证值按特定顺序合并。例如,如果您将其移植到Scala,则可能会导致结果完全混淆。

接下来,将RDD与单个项目放在一起是没有用的。如果你这样做:

  • 数据未分发 - 您就像拥有本地对象一样好。
  • 因此,处理并非真正并行化。

因此,如果您有一个项目,并希望:

  

对它应用更多转换。

只使用普通的Python对象。

wholeTextFiles更好吗?它不是。使用单个文件时,它会遇到与保留本地对象相同的问题。

  • 使用单个文件,所有数据都会转到一个分区。
  • 不分发处理。
  • 数据被急切加载而不是分发,因此当输入的大小增加时,您可能会发现执行程序失败。

最后wholeTextFiles实现效率相当低,因此PySpark中的总体内存占用量可能比数据大小的数倍。

您没有提供足够的上下文,但我会做出有根据的猜测并假设您想要分隔数据块。如果我是对的,您应该使用自定义delimitercreating spark data structure from multiline record):

rdd = sc.newAPIHadoopFile(
    '/tmp/asd.txt',
    'org.apache.hadoop.mapreduce.lib.input.TextInputFormat',
    'org.apache.hadoop.io.LongWritable',
    'org.apache.hadoop.io.Text',
    conf={'textinputformat.record.delimiter': '\n\n'}
).values()

会像这样分割你的数据:

rdd.take(3)
# ["hello\ni'm Arya\ni'm 21 yrold", "Hello\ni'm Jack\ni'm 30.", 'i am ali.']

答案 1 :(得分:0)

您可以使用wholeTextFiles函数来读取可以Tuple2(filename, text)的文件。 text是您尝试使用join创建的文件的全文。

rdd = sc.wholeTextFiles("asd.txt").map(lambda x : x[1])