用instanceOf Tuple过滤

时间:2018-07-26 19:40:15

标签: scala apache-spark

我正在尝试找到单词的同时出现。以下是我正在使用的代码。

val dataset = df.select("entity").rdd.map(row => row.getList(0)).filter(r => r.size() > 0).distinct()
println("dataset")

dataset.take(10).foreach(println)

示例数据集

dataset
[aa]
[bb]
[cc]
[dd]
[ee]
[ab, ac, ad]
[ff]
[ef, fg]
[ab, gg, hh]

代码段

case class tupleIn(a: String,b: String)
case class tupleOut(i: tupleIn, c: Long)
val cooccurMapping = dataset.flatMap(
list => {
    list.toArray().map(e => e.asInstanceOf[String].toLowerCase).flatMap(
        ele1 => {
            list.toArray().map(e => e.asInstanceOf[String].toLowerCase).map(ele2 => {
                if (ele1 != ele2) {
                    ((ele1, ele2), 1L)
                }
            })
        })
})

如何从中进行过滤?

我尝试过

.filter(e => e.isInstanceOf[Tuple2[(String, String), Long]])
  

:121:警告:没有结果的类型测试:Unit类型的值也不能是((String,String),Long)              .filter(e => e.isInstanceOf [Tuple2 [(String,String),Long]])                                         ^

     

:121:错误:isInstanceOf无法测试值类型是否为引用。              .filter(e => e.isInstanceOf [Tuple2 [(String,String),Long]])

.filter(e => e.isInstanceOf[tupleOut])
  

:122:警告:无效类型测试:类型值Unit   也不能成为coocrTupleOut              .filter(e => e.isInstanceOf [tupleOut])                                         ^:122:错误:isInstanceOf无法测试值类型是否为引用。              .filter(e => e.isInstanceOf [tupleOut])

如果我地图

.map(e => e.asInstanceOf[Tuple2[(String, String), Long]])

上面的代码片段工作正常,但在某些时候会出现此异常:

  

java.lang.ClassCastException:无法转换scala.runtime.BoxedUnit   到scala.Tuple2   $ line84834447093。$ read $$ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $$ iw $$ iw $$ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ anonfun $ 2 $$ anonfun $ 9.apply( :123)     在   $ line84834447093。$ read $$ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $$ iw $$ iw $$ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ iw $ anonfun $ 2 $$ anonfun $ 9.apply( :123)     在scala.collection.Iterator $$ anon $ 11.next(Iterator.scala:409)在   scala.collection.Iterator $$ anon $ 13.hasNext(Iterator.scala:462)在   org.apache.spark.util.collection.ExternalSorter.insertAll(ExternalSorter.scala:191)     在   org.apache.spark.shuffle.sort.SortShuffleWriter.write(SortShuffleWriter.scala:63)     在   org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:96)     在   org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:53)     在org.apache.spark.scheduler.Task.run(Task.scala:108)处   org.apache.spark.executor.Executor $ TaskRunner.run(Executor.scala:338)     在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)     在   java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624)     在java.lang.Thread.run(Thread.java:748)

为什么instanceOffilter()中不工作,而在map()中工作

1 个答案:

答案 0 :(得分:1)

代码的结果是收集类型为Unit的项目,因此filter和map都不会进行任何迭代(请注意map不会 as ,因此它将转换为您想要的类型,而as is is检查了类型)

无论如何,如果我正确理解了您的意图,则可以使用spark的内置函数获得所需的内容:

val l=List(List("aa"),List("bb","vv"),List("bbb"))
val rdd=sc.parallelize(l)
val df=spark.createDataFrame(rdd,"data")

import org.apache.spark.sql.functions._
val ndf=df.withColumn("data",explode($"data"))
val cm=ndf.select($"data".as("elec1")).crossJoin(ndf.select($"data".as("elec2"))).withColumn("cnt",lit(1L))
val coocurenceMap=cm.filter($"elec1" !== $"elec2")