Создание пустых разреженных векторов в PySpark

У меня есть фрейм данных DF1, который выглядит так:

+-------+------+
|user_id|meta  |
+-------+------+
|      1|  null|
|     11|  null|
|     15|  null|
+-------+------+

Схема:

root
 |-- user_id: string (nullable = true)
 |-- meta: string (nullable = true)

и у меня есть еще один фрейм данных DF2, который выглядит так

+-------+------------------------------------+
|user_id|            Vectorz                 |
+-------+------------------------------------+
|     10|                       (2,[1],[1.0])|
|     12|                       (2,[1],[1.0])|
|     13|                       (2,[0],[1.0])|
|     14|                       (2,[1],[1.0])|
---------------------------------------------

Схема:

[user_id: string, Vectorz: vector]

Я хочу вставить все user_ids из DF1 в DF2, но создать для них пустые разреженные векторы, поскольку их столбец «meta» - это все NULL.

Итак, я хочу, чтобы DF2 наконец был:

+-------+------------------------------------+
|user_id|            Vectorz                 |
+-------+------------------------------------+
|      1|                            (,[],[])|
|     10|                       (2,[1],[1.0])|
|     11|                            (,[],[])|
|     12|                       (2,[1],[1.0])|
|     13|                       (2,[0],[1.0])|
|     14|                       (2,[1],[1.0])|
|     15|                            (,[],[])|
---------------------------------------------

Может кто-нибудь помочь?

Я новичок в PySpark. Так что извините, если я недостаточно информирован.


person VictorCreator    schedule 20.05.2020    source источник
comment
Что ты пробовал? Вы можете попробовать добавить Vectorz в DF1, отбросить meta, а затем объединить оба dfs вместе.   -  person moon    schedule 20.05.2020
comment
Привет, ты можешь проверить мой ответ? пожалуйста, проголосуйте + примите, если это сработает для вас   -  person Som    schedule 22.05.2020


Ответы (1)


Вы можете пойти дальше и создать пустые векторы для всех user_ids, когда значение meta равно нулю. В любом случае вам нужно решить, когда мета-столбец не равен нулю.

Образец кода

  1. DF1
val spark = sqlContext.sparkSession
    val implicits = sqlContext.sparkSession.implicits
    import implicits._

    val df1 = sqlContext.range(1,4)
      .withColumnRenamed("id", "user_id")
      .withColumn("meta", lit(null).cast(DataTypes.StringType))
    df1.show(false)
    df1.printSchema()

      +-------+----+
      |user_id|meta|
      +-------+----+
      |1      |null|
      |2      |null|
      |3      |null|
      +-------+----+

    root
    |-- user_id: long (nullable = false)
    |-- meta: string (nullable = true)
  1. DF2
    import org.apache.spark.ml.linalg.Vectors
    val staticVector = udf(() => Vectors.sparse(5, Seq((1, 1.0), (3, 7.0))), SQLDataTypes.VectorType)
    val df2 = sqlContext.range(5,8)
      .withColumnRenamed("id", "user_id")
      .withColumn("Vectorz", staticVector())

    df2.show(false)
    df2.printSchema()

    +-------+-------------------+
    |user_id|Vectorz            |
    +-------+-------------------+
    |5      |(5,[1,3],[1.0,7.0])|
    |6      |(5,[1,3],[1.0,7.0])|
    |7      |(5,[1,3],[1.0,7.0])|
    +-------+-------------------+

    root
    |-- user_id: long (nullable = false)
    |-- Vectorz: vector (nullable = true)
  1. Обработанный DF
  val emptyVector = udf(() => Vectors.sparse(0, Array.empty[Int], Array.empty[Double]), SQLDataTypes.VectorType)

    val processedDF =
      // meta column shouldn't have any value
      // for the safer side adding filter as meta is null
      // need to decide what if meta is not null
      // I'm assigning empty vector to that also
      df1.where(col("meta").isNull)
        .withColumn("Vectorz", when(col("meta").isNull, emptyVector()).otherwise(emptyVector()))
        .drop("meta")
        .unionByName(df2)

    processedDF.show(false)
    processedDF.printSchema()

    +-------+-------------------+
    |user_id|Vectorz            |
    +-------+-------------------+
    |1      |(0,[],[])          |
    |2      |(0,[],[])          |
    |3      |(0,[],[])          |
    |5      |(5,[1,3],[1.0,7.0])|
    |6      |(5,[1,3],[1.0,7.0])|
    |7      |(5,[1,3],[1.0,7.0])|
    +-------+-------------------+

    root
    |-- user_id: long (nullable = false)
    |-- Vectorz: vector (nullable = true)


person Som    schedule 20.05.2020