使用.select()时,我遇到了令人惊讶的行为:

>>> my_df.show()
+---+---+---+
|  a|  b|  c|
+---+---+---+
|  1|  3|  5|
|  2|  4|  6|
+---+---+---+

>>> a_c = s_df.select(col("a"), col("c")) # removing column b
>>> a_c.show()
+---+---+
|  a|  c|
+---+---+
|  1|  5|
|  2|  6|
+---+---+

>>> a_c.filter(col("b") == 3).show() # I can still filter on "b"!
+---+---+
|  a|  c|
+---+---+
|  1|  5|
+---+---+

这种行为令我感到疑惑...我的以下观点正确吗?

DataFrames只是 View ,一个简单的DataFrame本身就是一个 View 。在我的情况下,a_c只是my_df的 View 。

当我创建a_c时,没有创建新数据,a_c指向的是my_df指向的相同数据。

如果还有其他相关信息,请添加!

最佳答案

这是由于Spark的惰性而发生的。它足够“聪明”,可以将过滤器向下推,使其发生在过滤器*之前的较低位置。因此,由于所有这些都发生在相同的执行stage中,因此仍然可以解决。实际上,您可以在explain中看到它:

== Physical Plan ==
*Project [a#0, c#2]
+- *Filter (b#1 = 3) <---Filter before Project
   +- LocalTableScan [A#0, B#1, C#2]

您可以强制改组并进入新的阶段,然后查看过滤器是否失败。甚至在编译时就将其捕获。这是一个例子:
a_c.groupBy("a","c").count.filter(col("b") === 3)

*还有一个投影修剪,如果它意识到在任何时候都不需要该列,则将选择向下推到数据库层。但是我相信过滤器会导致它“需要”它,而不是修剪……但是我没有对此进行测试。

关于apache-spark - .select()到底是做什么的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47934549/

10-11 22:22
查看更多