究竟是什么.select()呢?

Aka*_*all 7 apache-spark pyspark

使用时我遇到了令人惊讶的行为.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|
+---+---+
Run Code Online (Sandbox Code Playgroud)

这种行为让我感到疑惑......以下几点是否正确?

DataFrame只是视图,简单的DataFrame就是它自己的视图.在我的情况下a_c只是一个视图my_df.

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

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

Jus*_*ony 6

这是因为Spark的懒惰性质.足够"智能"将滤波器向下推,使其在滤波器*之前发生在较低的水平.所以,因为这一切都发生在执行的同一阶段,并且仍然可以解决.事实上,您可以在explain以下位置看到:

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

您可以强制进行随机播放和新阶段,然后查看您的过滤器失败.甚至在编译时捕获它.这是一个例子:

a_c.groupBy("a","c").count.filter(col("b") === 3)
Run Code Online (Sandbox Code Playgroud)

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