在RDD上调用collect()
会将整个数据集返回给驱动程序,导致内存不足,我们应该避免这种情况。
如果在数据帧上调用,collect()
会表现出相同的行为吗?
select()
方法怎么样?
如果在数据框上调用它是否也与collect()
的工作方式相同?
答案 0 :(得分:24)
- 收集(操作) - 在驱动程序中将数据集的所有元素作为数组返回。这通常在过滤器或之后有用 返回足够小的数据子集的其他操作。
select(* cols)(转换) - 投影一组表达式并返回一个新的DataFrame。
参数:cols - 列名(字符串)或表达式列表 (柱)。如果其中一个列名称为“*”,则会扩展该列 包括当前DataFrame中的所有列。**
df.select('*').collect() [Row(age=2, name=u'Alice'), Row(age=5, name=u'Bob')] df.select('name', 'age').collect() [Row(name=u'Alice', age=2), Row(name=u'Bob', age=5)] df.select(df.name, (df.age + 10).alias('age')).collect() [Row(name=u'Alice', age=12), Row(name=u'Bob', age=15)]
数据框上的执行select(column-name1,column-name2,etc)
方法返回一个新数据框,该数据框仅包含select()
函数中选定的列。
e.g。假设df
有几列,包括“name”和“value”以及其他一些列。
df2 = df.select("name","value")
df2
只会在df
df2作为select
的结果将在执行程序中而不在驱动程序中(如使用collect()
的情况)
df.printSchema()
# root
# |-- age: long (nullable = true)
# |-- name: string (nullable = true)
# Select only the "name" column
df.select("name").show()
# +-------+
# | name|
# +-------+
# |Michael|
# | Andy|
# | Justin|
# +-------+
您可以在数据框(spark docs)上运行collect()
>>> l = [('Alice', 1)]
>>> spark.createDataFrame(l).collect()
[Row(_1=u'Alice', _2=1)]
>>> spark.createDataFrame(l, ['name', 'age']).collect()
[Row(name=u'Alice', age=1)]
要打印驱动程序上的所有元素,可以使用collect()方法 首先将RDD带到驱动程序节点: rdd.collect()。的foreach(的println)。 这可能导致驱动程序耗尽 但是,因为collect()将整个RDD提取到a 单机;如果你只需要打印一些RDD元素,a 更安全的方法是使用take():rdd.take(100).foreach(println)。
答案 1 :(得分:4)
调用select
将导致lazy
评估:例如:
val df1 = df.select("col1")
val df2 = df1.filter("col1 == 3")
以上两个语句都会在您对df
调用操作时执行的延迟路径,例如show
,collect
等。
val df3 = df2.collect()
在转化结束时使用.explain
来遵循其计划
这里有更详细的信息Transformations and Actions
答案 2 :(得分:3)
直接回答问题:
如果在数据帧上调用,
collect()
的行为将相同吗?
是的,spark.DataFrame.collect
在功能上与spark.RDD.collect
相同。它们在这些不同的对象上具有相同的目的。
select()
方法怎么样?
没有spark.RDD.select
这样的东西,因此它不能与spark.DataFrame.select
相同。
如果在数据帧上调用,它是否也与
collect()
一样工作?
select
和collect
之间唯一相似的地方是它们都是DataFrame上的函数。它们的功能重叠绝对为零。
这是我自己的描述:collect
与sc.parallelize
相反。 select
与任何SQL语句中的SELECT
相同。
如果仍然难以理解collect
的实际功能(对于RDD或DataFrame),则需要查找一些有关火花在幕后进行的文章。例如:
答案 3 :(得分:2)
Select
用于投射dataframe
的部分或全部字段。它不会为您提供value
作为输出,而是为您提供新的dataframe
。它是transformation
。
答案 4 :(得分:1)
Select
是一个转换,而不是一个动作,因此它被懒惰地评估(实际上并不会只是映射操作来进行计算)。 Collect
是一个动作。
尝试:
df.limit(20).collect()
答案 5 :(得分:0)
以粗体显示的简短答案:
collect
主要用于序列化
(失去并行性,保留了数据帧的所有其他数据特征)
例如使用PrintWriter {{ 1}}您无法直接进行pw
,必须在df.foreach( r => pw.write(r) )
,collect
之前使用foreach
。
PS:“并行性损失”不是“全部损失”,因为在序列化之后它可以再次分配给执行者。
df.collect.foreach(etc)
主要用于选择列,类似于projection in relational algebra
(仅在框架上下文中类似,因为Spark select
不会进行重复数据删除数据)。
因此,它也是框架上下文中select
的补充。
评论其他答案:我喜欢{em> {em} 中的Jeff's classification of Spark operations(如filter
)和 actions (如select
)。还要记住,变换(包括collect
)是lazily evaluated。