请参考下面的示例代码:
sampleDf
->我要在2列startIPInt
和endIPInt
上过滤的示例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)
有人可以帮助我了解这里发生的事情吗?这是如上所述筛选和获取数据帧内容的正确,最快的方法。
答案 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隐式变量(使用$
表示法)就应该得到相同的结果。