pyspark列合并为一行
将 dataframe
利用 pyspark
列合并为一行,类似于 sql
的 GROUP_CONCAT
函数。例如如下 dataframe
:
+----+---+
| s| d|
+----+---+
|abcd|123|
| asd|123|
+----+---+
需要按照列相同的列 d
将 s
合并,想要的结果为:
+---+-----------+
| d| newcol|
+---+-----------+
|123|[abcd, xyz]|
+---+-----------+
利用 groupby
去实现就好,spark
里面可以用 concat_ws
实现,可以看这个 Spark中SQL列合并为一行,而这里的 concat_ws
合并缺很奇怪,官方文档的实例为:
>>> df = spark.createDataFrame([('abcd','123')], ['s', 'd'])
>>> df.select(concat_ws('-', df.s, df.d).alias('s')).collect()
[Row(s=u'abcd-123')]
作者自己尝试得到:
from pyspark.sql import SparkSession
from pyspark.sql.functions import concat_ws
# 初始化spark会话
spark = SparkSession \
.builder \
.appName("test") \
.master("local") \
.getOrCreate()
df = spark.createDataFrame([('abcd','123'),('xyz','123')], ['s', 'd'])
df.show()
df.select(concat_ws('-', df.s, df.d).alias('newcol')).show()
+--------+
| newcol|
+--------+
|abcd-123|
| xyz-123|
+--------+
不是想要的效果。而 collect_list
能得到相同的效果:
from pyspark.sql import SparkSession
from pyspark.sql.functions import concat_ws
from pyspark.sql.functions import collect_list
# 初始化spark会话
spark = SparkSession \
.builder \
.appName("test") \
.master("local") \
.getOrCreate()
df = spark.createDataFrame([('abcd','123'),('xyz','123')], ['s', 'd'])
df.show()
df.groupBy("d").agg(collect_list('s').alias('newcol')).show()
得到的结果为:
+---+-----------+
| d| newcol|
+---+-----------+
|123|[abcd, xyz]|
+---+-----------+
如果需要collect_list
多列,那么可以这么写:
from pyspark.sql import SparkSession
from pyspark.sql.functions import collect_set
# 初始化spark会话
spark = SparkSession \
.builder \
.appName("test") \
.master("local") \
.getOrCreate()
df = spark.createDataFrame([('abcd','123','456'),('xyz','123','789')], ['s', 'd','f'])
df.show()
df.groupBy("d").agg(*[collect_set(col) for col in ['s','f']]).show()
得到的结果为:
+---+--------------+--------------+
| d|collect_set(s)|collect_set(f)|
+---+--------------+--------------+
|123| [abcd, xyz]| [456, 789]|
+---+--------------+--------------+