在Spark数据框上对列值使用过滤器时出错

时间:2019-06-04 01:54:00

标签: scala apache-spark dataframe apache-spark-sql

请参考下面的示例代码:

sampleDf->我要在2列startIPIntendIPInt上过滤的示例Scala数据框。

var row = sampleDf.filter("startIPInt <=" + ip).filter("endIPInt >= " + ip)

我现在想查看该行的内容。 以下仅需花费几秒钟即可执行,但不会向我显示此行对象的内容:

println(row)

但是此代码执行所需的时间太长:

row.show()

所以我的问题是我应该如何查看该行对象的内容?还是我过滤数据框的方式有任何问题?

我最初的方法是使用此处提到的过滤器:https://spark.apache.org/docs/1.5.0/api/java/org/apache/spark/sql/DataFrame.html#filter(java.lang.String)

因此,以下代码行给我有关“重载方法'filter'”的错误:

var row = sampleDf.filter($"startIPInt" <= ip).filter($"endIPInt" >= ip)

有人可以帮助我了解这里发生的事情吗?这是如上所述筛选和获取数据帧内容的正确,最快的方法。

1 个答案:

答案 0 :(得分:1)

首先,使用filter并不会真正获得行/行对象,而是会获得一个新的数据框。

show执行时间更长的原因是由于Spark懒惰。仅在对数据帧采取操作时才会计算转换(例如,参见Spark Transformation - Why its lazy and what is the advantage?)。在数据帧上使用println不会执行任何操作,并且实际上不会计算过滤器转换。另一方面,show需要一些计算,这就是执行速度较慢的原因。

使用

sampleDf.filter("startIPInt <=" + ip).filter("endIPInt >= " + ip)

sampleDf.filter($"startIPInt" <= ip).filter($"endIPInt" >= ip)

是等效的,并且只要导入了Spark隐式变量(使用$表示法)就应该得到相同的结果。