Scala spark не может получить доступ к кортежу после плоской карты с выходом - PullRequest
0 голосов
/ 13 октября 2018
    val test_rated = pearson.flatMap(x => {
        val bid1 = x._1._1.toInt
        val bid2 = x._1._2.toInt
        val sim = x._2.toDouble

        val pairs = for (tu <- test_users) yield {
            val tid = tu.toInt
            if (test_map.contains((tid, bid2)) && train_map.contains((tid, bid1))){
                ((tid, bid2), (bid1, sim))
            }
        }
        pairs
    }).filter(row => row!= ())

В этом блоке кода test_users - это scala list.После операции flatMap с yield я смог получить результат и распечатать его с помощью foreach.Однако, если я хочу отобразить его снова как

test_rated.map(x => x._2)

, я не смог бы получить доступ к каждому отдельному значению кортежа с помощью x._2

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Предполагая, что остальная часть кода верна и типы совпадают (невозможно сказать без [mcve])), вы просто делаете это неправильно.Давайте упростим процесс, чтобы показать, почему:

scala> for {
     | x <- 1 to 5
     | } yield { if (x % 2 == 0) x}
res0: scala.collection.immutable.IndexedSeq[AnyVal] = Vector((), 2, (), 4, ())

Как видите, тип не Seq[Int], а Seq[AnyVal].Фильтрация данных не изменит это:

scala> res0.filter(x => x != ())
res1: scala.collection.immutable.IndexedSeq[AnyVal] = Vector(2, 4)

Вы можете collect:

scala> res0.collect { case x: Int => x}
res2: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)

, но на самом деле вы должны использовать защитное выражение:

scala> for {
     | x <- 1 to 5 if x % 2 == 0
     | } yield x
res3: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4)

поэтому ваш код должен быть переписан как:

val test_rated = pearson.flatMap(x => {
    val bid1 = x._1._1.toInt
    val bid2 = x._1._2.toInt
    val sim = x._2.toDouble

    def keep(tid) = {
      test_map.contains((tid, bid2)) && train_map.contains((tid, bid1))
    }

    for {
      tid <- test_users.map(_.toInt) if keep(tid)
    } yield ((tid, bid2), (bid1, sim))
})
0 голосов
/ 13 октября 2018

Я считаю, что блок кода в flatMap() не оценивается ни для одного объекта.Вы должны либо удалить val pairs =, либо явно вернуть pairs - например,

pearson.flatMap(x => { 
  ... 
  val pairs = ...
  pairs
}).filter(...)
...