Pyspark DataFrame:将具有多个值的列拆分为行

时间:2019-07-16 23:47:48

标签: apache-spark pyspark apache-spark-sql pyspark-sql

我有一个数据框(具有更多的行和列),如下所示。

样本DF:

$data

我想要什么:

from pyspark import Row
from pyspark.sql import SQLContext
from pyspark.sql.functions import explode

sqlc = SQLContext(sc)

df = sqlc.createDataFrame([Row(col1 = 'z1', col2 = '[a1, b2, c3]', col3 = 'foo')])
# +------+-------------+------+
# |  col1|         col2|  col3|
# +------+-------------+------+
# |    z1| [a1, b2, c3]|   foo|
# +------+-------------+------+

df
# DataFrame[col1: string, col2: string, col3: string]

我尝试复制此处提供的+-----+-----+-----+ | col1| col2| col3| +-----+-----+-----+ | z1| a1| foo| | z1| b2| foo| | z1| c3| foo| +-----+-----+-----+ 解决方案:Pyspark: Split multiple array columns into rows

RDD

但是,它没有提供所需的结果

编辑:(df .rdd .flatMap(lambda row: [(row.col1, col2, row.col3) for col2 in row.col2)]) .toDF(["col1", "col2", "col3"])) 选项不起作用,因为它当前存储为字符串,并且explode函数需要一个数组

2 个答案:

答案 0 :(得分:2)

尽管这是另一种使用regexp_extract的解决方案(在这种情况下,您实际上不需要替换任何东西),但Pault的解决方案应该可以正常工作。

from pyspark.sql.functions import col, explode, regexp_extract,regexp_replace, split

df.withColumn("col2", 
              explode(
                  split(
                      regexp_extract(
                        regexp_replace(col("col2"), "\s", ""), "^\[(.*)\]$", 1), ","))) \
.show()

说明:

  • 最初regexp_replace(col("col2"), "\s", "")将所有空格替换为空字符串。
  • 接下来的regexp_extract将提取以[开始并以]结束的列的内容。
  • 然后我们对逗号分隔的值执行split,最后执行explode

答案 1 :(得分:1)

您可以使用explode,但首先必须将数组的字符串表示形式转换为数组。

一种方法是使用regexp_replace删除前和后方括号,然后在", "上删除split

from pyspark.sql.functions import col, explode, regexp_replace, split

df.withColumn(
    "col2", 
    explode(split(regexp_replace(col("col2"), "(^\[)|(\]$)", ""), ", "))
).show()
#+----+----+----+
#|col1|col2|col3|
#+----+----+----+
#|  z1|  a1| foo|
#|  z1|  b2| foo|
#|  z1|  c3| foo|
#+----+----+----+
相关问题