如何基于ID将多行合并到单个单元格中,然后计数



如何使用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|
+--------------+-----+

相关内容

最新更新