Как сравнить несколько полей в объекте с очередью объектов?

Давайте начнем с некоторых фиктивных данных:

val transactions = Seq((1, 2), (1, 4), (2, 3)).toDF("user_id", "category_id")

val transactions_with_counts = transactions
  .groupBy($"user_id", $"category_id")
  .count

transactions_with_counts.printSchema

// root
// |-- user_id: integer (nullable = false)
// |-- category_id: integer (nullable = false)
// |-- count: long (nullable = false)

Существует несколько способов получить доступ к значениям Row и сохранить ожидаемые типы:

  1. Учет соответствия
    import org.apache.spark.sql.Row
    
    transactions_with_counts.map{
      case Row(user_id: Int, category_id: Int, rating: Long) =>
        Rating(user_id, category_id, rating)
    } 
    
  2. Настроены методы get*, такие как getInt, getLong:
    transactions_with_counts.map(
      r => Rating(r.getInt(0), r.getInt(1), r.getLong(2))
    )
    
  3. getAs метод, который может использовать как имена, так и индексы:
    transactions_with_counts.map(r => Rating(
      r.getAs[Int]("user_id"), r.getAs[Int]("category_id"), r.getAs[Long](2)
    ))
    
    Это может быть используется для правильного извлечения определенных пользователем типов, включая mllib.linalg.Vector. Очевидно, что для доступа по имени требуется схема.
  4. Преобразование в статически типизированное Dataset (Spark 1.6+ / 2.0+):
    transactions_with_counts.as[(Int, Int, Long)]
    
0
задан Roro 14 February 2019 в 17:52
поделиться