Эффективно транспонировать / разбивать столбцы искрового информационного кадра в строки в новом формате таблицы / информационного кадра [pyspark] - PullRequest
1 голос
/ 16 марта 2020

Как эффективно взорвать фрейм данных pyspark следующим образом:

+----+-------+------+------+
| id |sport  |travel| work |
+----+-------+------+------+
| 1  | 0.2   | 0.4  | 0.6  |
+----+-------+------+------+
| 2  | 0.7   | 0.9  | 0.5  |
+----+-------+------+------+

, и мой желаемый вывод такой:

+------+--------+  
| c_id | score  |  
+------+--------+  
| 1    | 0.2    |  
+------+--------+  
| 1    | 0.4    |  
+------+--------+  
| 1    | 0.6    |  
+------+--------+  
| 2    | 0.7    |  
+------+--------+  
| 2    | 0.9    |  
+------+--------+  
| 2    | 0.5    |  
+------+--------+  

1 Ответ

2 голосов
/ 16 марта 2020

Сначала вы можете поместить ваши 3 столбца в array, затем arrays_zip их, а затем explode их и распаковать их с помощью .*, затем select и переименовать разархивированный столбец.

df.withColumn("zip", F.explode(F.arrays_zip(F.array("sport","travel","work"))))\
  .select("id", F.col("zip.*")).withColumnRenamed("0","score").show()

+---+-----+
| id|score|
+---+-----+
|  1|  0.2|
|  1|  0.4|
|  1|  0.6|
|  2|  0.7|
|  2|  0.9|
|  2|  0.5|
+---+-----+

Вы также можете сделать это без arrays_zip (как упомянуто cPak). Arrays_zip используется для объединения массивов в разных столбцах фрейма данных для структурирования формы, так что вы можете разбить их все вместе, а затем выбрать с помощью. *. Для этого случая вы можете просто использовать:

df.withColumn("score", F.explode((F.array(*(x for x in df.columns if x!="id"))))).select("id","score").show()
...