Spark和Python使用自定义文件格式/生成器作为RDD的输入

时间:2014-10-03 10:27:30

标签: python hadoop apache-spark

我想问一下Spark中的输入可能性。我可以从http://spark.apache.org/docs/latest/programming-guide.html看到,我可以使用sc.textFile()将文本文件读取到RDD,但是我希望在分发到RDD之前进行一些预处理,例如我的文件可能是以JSON格式,例如。 {id:123, text:"...", value:6}我想仅使用JSON的某些字段进行进一步处理。

我的想法是,是否有可能以某种方式使用Python生成器作为SparkContext的输入?

或者如果在Spark中有一些更自然的方式如何处理自定义文件,而不是Spark文本文件?

修改

似乎接受的答案应该有效,但它让我更加接受我更实际的后续问题Spark and Python trying to parse wikipedia using gensim

2 个答案:

答案 0 :(得分:2)

执行此操作的最快方法可能是按原样加载文本文件,然后进行处理以在生成的RDD上选择所需的字段。这使整个集群中的工作并行化,并且比在单个机器上进行任何预处理更有效地扩展。

对于JSON(甚至是XML),我认为您不需要自定义输入格式。由于PySpark在Python环境中执行,因此您可以使用Python中常用的函数来反序列化JSON并提取所需的字段。

例如:

import json

raw = sc.textFile("/path/to/file.json")
deserialized = raw.map(lambda x: json.loads(x))
desired_fields = deserialized.map(lambda x: x['key1'])

desired_fields现在是原始JSON文件中key1下所有值的RDD。

您可以使用此模式提取字段组合,按空格分割它们等等。

desired_fields = deserialized.map(lambda x: (x['key1'] + x['key2']).split(' '))

如果这太复杂了,你可以用常规的Python函数替换lambda,它可以完成你想要的所有预处理,只需要调用deserialized.map(my_preprocessing_func)

答案 1 :(得分:1)

是的,您可以使用SparkContext.parallelize()

从python变量创建RDD
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)
distData.count()   # 5

此变量也可以是迭代器。