Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spark和Python使用自定义文件格式/生成器作为RDD的输入_Python_Hadoop_Apache Spark - Fatal编程技术网

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

Spark和Python使用自定义文件格式/生成器作为RDD的输入,python,hadoop,apache-spark,Python,Hadoop,Apache Spark,我想问一下Spark中的输入可能性。我可以从中看出,我可以使用sc.textFile()将文本文件读取到RDD,但我想在分发到RDD之前做一些预处理,例如,我的文件可能是JSON格式的,例如{id:123,text:“…”,value:6}我只想使用JSON的某些字段进行进一步处理 我的想法是,是否有可能以某种方式使用Python生成器作为SparkContext的输入 或者,如果Spark中有更自然的方式来处理自定义文件,而不是Spark的纯文本文件 编辑: 似乎接受的答案应该是可行的,但这让

我想问一下Spark中的输入可能性。我可以从中看出,我可以使用
sc.textFile()
将文本文件读取到RDD,但我想在分发到RDD之前做一些预处理,例如,我的文件可能是JSON格式的,例如
{id:123,text:“…”,value:6}
我只想使用JSON的某些字段进行进一步处理

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

或者,如果Spark中有更自然的方式来处理自定义文件,而不是Spark的纯文本文件

编辑:


似乎接受的答案应该是可行的,但这让我想到了下面更实际的问题

是的,您可以使用
SparkContext.parallelize()从python变量创建RDD:


此变量也可以是迭代器。

最快的方法可能是按原样加载文本文件,并进行处理以在生成的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'])
required_fields
现在是原始JSON文件中
key1
下所有值的RDD

您可以使用此模式提取字段的组合、按空格分割字段或其他方式

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

如果这变得太复杂,您可以用一个常规Python函数替换
lambda
,该函数可以执行您想要的所有预处理,只需调用
deserialized.map(my_preprocessing_func)

就可以将JSON加载到RDD中,然后在RDD上进行处理,以仅过滤您需要的数据。这样做的好处是,这种“预处理”类型的工作可以在Spark集群中并行化。你能举一个例子说明你想先做什么样的处理吗?通过预处理,我的主要意思是我只想从JSON或XML中选择例如字段text1,text2,然后我可以做一些事情,比如用空格分割它并将其保存为文本文件。我看不到任何解析JSON RDD的自然方法。现在,我只能考虑将JSON或XML作为sc.textFile()文件进行处理,只要看到所需的键,就使用以下字符串。那是你的意思吗?是的,我想我对你想做的事有感觉。如果我误解了,请评论我的答案。我正在尝试实现并运行这个示例,所以我会在我成功后尽快让您知道这是否对我有效。我现在很惊讶这真的能起作用,因为例如,我的JSON可能比所有机器的RAM内存都大,所以我希望一次只加载一部分,因此JSON.loads(x)只会得到一部分,它将无法正确解析它?实际上这应该能起作用,但这让我想到了@ziky90中的一个特别的后续问题:“我的JSON可能比所有机器的RAM内存都大”,这不应该是一个问题。如果源数据集中每行有一个JSON对象,Spark将能够很好地处理它,即使数据集很大。即使您尝试缓存数据集,Spark也会尽可能多地缓存数据,并处理磁盘中的其余数据。不幸的是,当生成器生成的列表大于RAM内存时,这将不起作用,因为Spark会在内部将生成器转换为列表。你对这里的解决办法有什么想法吗?我担心情况会是这样。很抱歉,除了在Spark中进行所有处理或尝试修补源代码之外,我不知道如何进一步处理。
desired_fields = deserialized.map(lambda x: (x['key1'] + x['key2']).split(' '))