如何使用pyspark根据ID将多个行合并到单个单元格中?我有一个带有ID和产品的数据框。首先,我想将产品与相同的ID合并到列表中,然后我想计算每个唯一列表的出现数量。
输入示例1:
id,product
1,HOME
1,mobile
2,watch
2,mobile
3,HOME
3,mobile
4,cd
4,music
4,video
输出:
product,count
HOME-mobile,2
mobile-watch,1
cd-music-video,1
带有SQL代码的示例2:
输入示例:
cloths,brad
cloths,edu
cloths,keith
cloths,stef
enter,andr
enter,char
enter,danny
enter,lucas
代码:
SELECT
SS.SEC_NAME,
STUFF((SELECT '- ' + US.USR_NAME
FROM USRS US
WHERE US.SEC_ID = SS.SEC_ID
ORDER BY USR_NAME
FOR XML PATH('')), 1, 1, '') [SECTORS/USERS]
FROM SALES_SECTORS SS
GROUP BY SS.SEC_ID, SS.SEC_NAME
ORDER BY 1
输出:
cloths,brad-edu-keith-stef
enter,andr-char-danny-lucas
在此示例中,输出没有计数,但应包括在内。
我想在pyspark而不是sql/pig中解决这个问题。
您可以使用 groupby
做到这一点。ID列上的第一组,将产品合并为一个单一的排序列表。要获取此类列表数量的计数,请再次使用groupby
,然后按count
进行汇总。
from pyspark.sql import functions as F
df2 = (df
.groupby("id")
.agg(F.concat_ws("-", F.sort_array(F.collect_list("product"))).alias("products"))
.groupby("products")
.agg(F.count("id")).alias("count"))
这应该为您提供这样的数据框架:
+--------------+-----+
| products|count|
+--------------+-----+
| HOME-mobile| 2|
| mobile-watch| 1|
|cd-music-video| 1|
+--------------+-----+