Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 即使列不在数据帧中,Spark也会向下推一个过滤器_Scala_Apache Spark - Fatal编程技术网

Scala 即使列不在数据帧中,Spark也会向下推一个过滤器

Scala 即使列不在数据帧中,Spark也会向下推一个过滤器,scala,apache-spark,Scala,Apache Spark,我有一个DataFrame,其中包含以下列: field1,field1\u名称,field3,field5,field4,field2,field6 我选择它是为了只保留field1、field2、field3、field4。请注意,选择后没有字段5 在此之后,我有一个使用field5的过滤器,我希望它抛出一个分析错误,因为列不在那里,但它正在过滤原始数据帧(在选择之前),因为它正在向下推过滤器,如下所示: == Parsed Logical Plan == 'Filter ('field5

我有一个
DataFrame
,其中包含以下列:

field1,field1\u名称,field3,field5,field4,field2,field6

我选择它是为了只保留
field1、field2、field3、field4
。请注意,选择后没有
字段5

在此之后,我有一个使用
field5
的过滤器,我希望它抛出一个分析错误,因为列不在那里,但它正在过滤原始
数据帧(在选择之前),因为它正在向下推过滤器,如下所示:

== Parsed Logical Plan ==
'Filter ('field5 = 22)
+- Project [field1#43, field2#48, field3#45, field4#47]
+- Relation[field1#43,field1_name#44,field3#45,field5#46,field4#47,field2#48,field6#49] csv

== Analyzed Logical Plan ==
field1: string, field2: string, field3: string, field4: string
Project [field1#43, field2#48, field3#45, field4#47]
+- Filter (field5#46 = 22)
+- Project [field1#43, field2#48, field3#45, field4#47, field5#46]
+- Relation[field1#43,field1_name#44,field3#45,field5#46,field4#47,field2#48,field6#49] csv

== Optimized Logical Plan ==
Project [field1#43, field2#48, field3#45, field4#47]
+- Filter (isnotnull(field5#46) && (field5#46 = 22))
+- Relation[field1#43,field1_name#44,field3#45,field5#46,field4#47,field2#48,field6#49] csv

== Physical Plan ==
  *Project [field1#43, field2#48, field3#45, field4#47]
+- *Filter (isnotnull(field5#46) && (field5#46 = 22))
+- *FileScan csv [field1#43,field3#45,field5#46,field4#47,field2#48] Batched: false, Format: CSV, Location: InMemoryFileIndex[file:/Users/..., PartitionFilters: [], PushedFilters: [IsNotNull(field5), EqualTo(field5,22)], ReadSchema: struct<field1:string,field3:string,field5:string,field4:stri...
输出:

+------+------+
|field1|field2|
+------+------+
+------+------+
上的文档描述了您观察得非常好的原因:

“数据集”是“懒惰的”,即仅当调用某个操作时才会触发计算在内部,数据集表示描述生成数据所需计算的逻辑计划。调用操作时,Spark的查询优化器优化逻辑计划并生成物理计划,以并行和分布式方式高效执行。"

重要部分以粗体突出显示。当应用
select
filter
语句时,它只是被添加到一个逻辑计划中,当应用一个操作时,该逻辑计划仅由Spark解析。在解析这个完整的逻辑计划时,Catalyst Optimizer查看整个计划,其中一个优化规则是按下filters,这是您在示例中看到的

我认为这是一个很好的特性。尽管您对在最终数据帧中看到这个特定字段不感兴趣,但它知道您对一些原始数据不感兴趣


这是Spark SQL engine相对于RDD的主要优势。它理解你想做什么,而没有人告诉怎么做。

谢谢你的回答。我知道
数据帧
是懒惰的。老实说,我不认为这是这里的问题。我同意在
完成之前不进行评估示例中的how
操作。我的观点是,如果select不包含过滤器中使用的字段,我不希望过滤器被压到select下方……不确定这是expectec行为还是错误。是的,这是预期行为。我已经添加了几句话。希望这会澄清。我发现这有点误导老实说,非常感谢您的澄清!如果您在所选的
中添加一个
(并将执行计划分为两部分),您将得到预期的异常。