pyspark RDD.foreach()和www.example.com()之间的差异RDD.map

8wtpewkr  于 2023-01-20  发布在  Spark
关注(0)|答案(2)|浏览(153)

我正在学习Python中的Spark,想知道有人能解释一下动作foreach()和变换map()之间的区别吗?
rdd.map()返回一个新的RDD,就像Python中原来的map函数一样,不过我想看一个rdd.foreach()函数,了解一下其中的区别,谢谢!

sy5wg1nm

sy5wg1nm1#

一个非常简单的例子是rdd.foreach(print),它将打印RDD中每一行的值,但不以任何方式修改RDD。
例如,这将生成一个包含数字1 - 10的RDD:

>>> rdd = sc.parallelize(xrange(0, 10)).map(lambda x: x + 1)
>>> rdd.take(10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

map调用为每一行计算一个新值,并返回,这样我就得到了一个新的RDD,但是,如果我使用foreach,它将是无用的,因为foreach不会以任何方式修改RDD:

>>> rdd = sc.parallelize(range(0, 10)).foreach(lambda x: x + 1)
>>> type(rdd)
<class 'NoneType'>

相反,在返回None(如print)的函数上调用map并不是很有用:

>>> rdd = sc.parallelize(range(0, 10)).map(print)
>>> rdd.take(10)
0
1
2
3
4
5
6
7
8
9
[None, None, None, None, None, None, None, None, None, None]

print调用返回None,所以Map只给你一堆None值,你不需要这些值,也不想保存它们,所以返回它们是浪费。(注意12,等是正在执行的print,因为RDD是延迟执行的,所以它们直到调用take时才会出现,但是RDD的内容只是一堆None
更简单地说,如果你关心函数的返回值,就调用map;如果你不关心,就调用foreach

fnx2tebb

fnx2tebb2#

Map是一种转换,因此当您执行一个map时,您可以对RDD中的每个元素应用一个函数,并返回一个新的RDD,在其中可以调用其他转换或操作。
Foreach是一个动作,它接受每个元素并应用一个函数,但不返回值。这在你必须调用RDD执行一些计算并在其他地方记录结果时特别有用,例如数据库或调用API处理RDD中的每个元素。
例如,假设您有一个RDD,其中包含许多您希望登录到另一个系统的查询,这些查询存储在RDD中。

queries = <code to load queries or a transformation that was applied on other RDDs>

然后,您需要通过调用另一个API将这些查询保存在另一个系统中

import urllib2

def log_search(q):
    response = urllib2.urlopen('http://www.bigdatainc.org/save_query/' + q)

queries.foreach(log_search)

现在您已经在RDD的每个元素上执行了log_query,如果您已经完成了Map,那么在您调用一个操作之前,什么也不会发生。

相关问题