Spark数据帧:collect()vs select()

Mri*_*nal 24 bigdata dataframe apache-spark apache-spark-sql

调用collect()RDD会将整个数据集返回给驱动程序,这会导致内存不足,我们应该避免这种情况.

collect()如果在数据帧上调用,它的行为方式会相同吗?方法怎么
select()
它是否也像collect()在数据帧上调用一样工作?

Yar*_*ron 37

行动与转型

  • 收集(操作) - 在驱动程序中将数据集的所有元素作为数组返回.在过滤器或其他返回足够小的数据子集的操作之后,这通常很有用.

spark-sql doc

select(*cols)(transformation) - 投影一组表达式并返回一个新的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)]
Run Code Online (Sandbox Code Playgroud)

select(column-name1,column-name2,etc)对数据帧执行方法,返回一个新的数据帧,该数据帧仅包含在select()函数中选择的列.

例如,假设df有几列包括"名称"和"值"以及其他一些列.

df2 = df.select("name","value")
Run Code Online (Sandbox Code Playgroud)

df2 将只包含两列("name"和"value") df

df2作为结果select将在执行程序而不是在驱动程序中(如在使用的情况下collect())

SQL编程导向

df.printSchema()
# root
# |-- age: long (nullable = true)
# |-- name: string (nullable = true)

# Select only the "name" column
df.select("name").show()
# +-------+
# |   name|
# +-------+
# |Michael|
# |   Andy|
# | Justin|
# +-------+
Run Code Online (Sandbox Code Playgroud)

您可以collect()在数据框架上运行(spark docs)

>>> 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)]
Run Code Online (Sandbox Code Playgroud)

火花文档

要打印驱动程序上的所有元素,可以使用collect()方法首先将RDD带到驱动程序节点:rdd.collect().foreach(println).但是,这会导致驱动程序内存不足,因为collect()会将整个RDD提取到一台机器上 ; 如果你只需要打印一些RDD元素,更安全的方法是使用take():rdd.take(100).foreach(println).

  • 我觉得这是对“select”的很好解释,但我仍然不明白“collect”的作用。如果您没有“collect()”,您的所有示例将返回什么? (3认同)

Mul*_*ter 7

直接回答问题:

如果在数据帧上调用,行为会collect()相同吗?

是的,spark.DataFrame.collect在功能上与 相同spark.RDD.collect。它们在这些不同的物体上具有相同的目的。

方法又如何呢select()

不存在“ ”这样的东西spark.RDD.select,所以它不能与“ ”相同spark.DataFrame.select

collect()它的工作方式是否与在数据帧上调用相同?

select和之间唯一相似的collect是它们都是 DataFrame 上的函数。它们在功能上绝对零重叠。

这是我自己的描述:collect与 相反sc.parallelizeselect与任何 SQL 语句中的相同SELECT

如果您仍然无法理解 Spark 的collect实际作用(对于 RDD 或 DataFrame),那么您需要查找一些有关 Spark 在幕后所做的事情的文章。例如:


Raj*_*hra 6

Select用于投影 a 的部分或所有字段dataframe。它不会给你一个value作为输出,而是一个新的dataframe. 它的一个transformation.


Kar*_*dol 6

调用select结果将是lazy评估结果:例如:

val df1 = df.select("col1")
val df2 = df1.filter("col1 == 3")
Run Code Online (Sandbox Code Playgroud)

上述两种语句创建,当你调用该动作将被执行懒惰路径df,如showcollect等。

val df3 = df2.collect()
Run Code Online (Sandbox Code Playgroud)

.explain在转换结束时使用以遵循其计划,此处提供了更详细的信息转换和操作


Jas*_*son 5

Select是一个转换,而不是一个操作,因此它是惰性评估的(实际上不会进行计算,只是映射操作)。Collect是一个动作。

尝试:

df.limit(20).collect()