Использование PySpark для создания аккуратного фрейма данных из массивов - PullRequest
0 голосов
/ 01 августа 2020

У меня есть фрейм данных Spark, который имеет два массива, как показано ниже:

df = spark.createDataFrame(
  [((["Person", "Company", "Person", "Person"], 
     ["John", "Company1", "Jenny", "Jessica"]))], 
  ["Type", "Value"])
df.show()

+--------------------+--------------------+
|                Type|               Value|
+--------------------+--------------------+
|[Person, Company,...|[John, Company1, ...|
+--------------------+--------------------+

Я хочу преобразовать его в аккуратную версию, которая выглядит так:

df = spark.createDataFrame(
    [
        ("Person", "John"), 
        ("Company", "Company1"), 
        ("Person", "Jenny"), 
        ("Person", "Jessica"),
    ],
    ["Type", "Value"])
df.show()

+-------+--------+
|   Type|   Value|
+-------+--------+
| Person|    John|
|Company|Company1|
| Person|   Jenny|
| Person| Jessica|
+-------+--------+

PySpark или Spark SQL решений оценены. TIA.

1 Ответ

1 голос
/ 01 августа 2020

From Spark-2.4.0 Используйте функцию arrays_zip для сжатия двух массивов (списков), затем выполните explode.

For Spark < 2.4 используйте udf для создания zip.

Example:

df = spark.createDataFrame(
  [((["Person", "Company", "Person", "Person"], 
     ["John", "Company1", "Jenny", "Jessica"]))], 
  ["Type", "Value"])

from pyspark.sql.functions import *
df.withColumn("az",explode(arrays_zip(col("Type"),col("Value")))).select("az.*").show()
#+-------+--------+
#|   Type|   Value|
#+-------+--------+
#| Person|    John|
#|Company|Company1|
#| Person|   Jenny|
#| Person| Jessica|
#+-------+--------+

#using spark sql
df.createOrReplaceTempView("tmp")
sql("select col.* from (select explode(arrays_zip(Type,Value)) from tmp)q").show()
#+-------+--------+
#|   Type|   Value|
#+-------+--------+
#| Person|    John|
#|Company|Company1|
#| Person|   Jenny|
#| Person| Jessica|
#+-------+--------+
...