火花过滤不起作用

时间:2017-10-22 08:31:10

标签: scala apache-spark spark-dataframe

我试图在我的Dataframe [Row]上过滤一些值。问题如下:

var index : Int = 0
var set = SetBuilding(features, 3)
val soglia : Int = 30
var exit : Boolean = false

while (!exit && index<set.length){
 val attributes = set(index).split(",")
 var r = scala.util.Random
 var i = r.nextInt(attributes.length)
 var previousI = i
 var j : Int = 8
 var maxprojections : Int = 5 
 var dataframe = sqlContext.sql("SELECT "+set(index)+" FROM table").cache()
println("**************VALUTAZIONE SOTTOINSIEME: "+ set(index)+"***********************" )

 while ( j!=0 && maxprojections >=0){

var filtered = dataframe.filter((elem : Row) => ReturnType(elem.get(elem.fieldIndex(attributes(i)))).>(soglia))
println ( "proiezione su attributo " + attributes (i))
for (elem <- filtered){
  println(elem)
}
if ( attributes.size != 1){
 do{
   i = r.nextInt(attributes.length)
 }while ( i == previousI )
}
     println ( "*********valore di previousI = "+ attributes(previousI)+ "******************************")

 previousI = i

 j = filtered.count().toInt   
 println ( "*********valore di j = "+ j+ "******************************")
 maxprojections = maxprojections - 1
 println ( "*********valore di maxproj = "+ maxprojections+ "******************************")
}
 index+=1
 if ( index >= 4)
   exit = true
}

问题在于,如果我将数据结构维护为spark.DataFrame并调用filter(),则在某些属性上我希望返回一个空数据帧但调用filteredData.count的值为!= 0,但是我和#39;请确保这些值小于阈值。

当我在filteredData上调用collect()时,不会发生此问题。

是否有解决方案包括将 filteredData 维护为 DataFrame

我希望现在查询很好了

1 个答案:

答案 0 :(得分:2)

似乎在问题的上下文中的预期是每个filter操作都会使Dataframe变异,从而有效地从中移除元素。

这是一个不正确的假设。

每个数据帧代表一组不可变的数据。 在循环的每次迭代中,我们获得的新数据帧是使用单个条件进行过滤的结果。 所以在每个循环中结果如下:

/** loop 1 **/ var filtered = dataframe.filter(attibute_1 > threshold)
/** loop 2 **/ var filtered = dataframe.filter(attibute_2 > threshold)
...
/** loop n **/ var filtered = dataframe.filter(attibute_n > threshold)

我们最后观察到的是最终过滤操作覆盖变量var filtered = dataframe.filter(attibute_n > threshold)的结果。所有其他过滤操作都将丢失。

如果我们想要迭代地删除此上下文中的元素,那么实现这一目标的快速更改是通过利用可变变量将过滤器堆叠在循环中。像这样:

var filtered = dataframe
while (cond) {
    filtered = filtered.filter(attibute_i > threshold)
}

此处生成的filtered数据框具有逻辑计划,该逻辑计划由彼此跟随的多个过滤操作组成。 它等同于:dataframe.filter(attibute1 > threshold).filter(attribute2 > threshold).filter(attribute3 > threshold)...