我有以下包含 4 列(A、B、C、D)的資料框:
df =
| 一個 | 乙 | C | D |
|---|---|---|---|
| 123 | 001 | 美國廣播公司 | 國防軍 |
| 123 | 001 | 美國廣播公司 | 度 |
| 256 | 002 | XXY | 動態搜索廣告 |
| 256 | 002 | XXX | 動態搜索廣告 |
從上面的資料框中,我想按列 A 和 B 分組,并通過分號 ';' 聚合和連接 按 C 和 D 列,同時確保沒有連接重復值。下面是預期的結果。
df_agg =
| 一個 | 乙 | C | D |
|---|---|---|---|
| 123 | 001 | 美國廣播公司 | DEF;度; |
| 256 | 002 | XXY;XXX; | 動態搜索廣告 |
我目前有下面的 groupby 函式,但它似乎沒有洗掉重復的字串,而是連接整個字串。
df_agg = df.groupby(groupby_list).agg( *[array_join(collect_list(column), ";").alias(column) for column in df.columns if column not in groupby_list] )
另外,我如何確保添加';' 回圈結束后?
uj5u.com熱心網友回復:
您需要使用聚合collect_set- 它洗掉重復項。array_join在元素之間添加分隔符。concat將結果與;末尾的字串或空字串連接起來。
from pyspark.sql import functions as F
df = spark.createDataFrame(
[(123, '001', 'ABC', 'DEF'),
(123, '001', 'ABC', 'DEG'),
(256, '002', 'XXY', 'DSA'),
(256, '002', 'XXX', 'DSA')],
['A', 'B', 'C', 'D']
)
df_agg = df.groupBy('A', 'B').agg(
*[F.concat(F.array_join(F.collect_set(c), ';'),
F.when(F.size(F.collect_set(c)) > 1, ';').otherwise('')).alias(c)
for c in {'C', 'D'}]
)
df_agg.show()
# --- --- -------- --------
# | A| B| C| D|
# --- --- -------- --------
# |123|001| ABC|DEF;DEG;|
# |256|002|XXX;XXY;| DSA|
# --- --- -------- --------
uj5u.com熱心網友回復:
groupby并且collect_set, set 只取唯一值。使用array_join函式將陣列元素與所需的分隔符連接起來。下面的代碼
df.groupby('A','B').agg(*[array_join(collect_set(x),';').alias(x) for x in df.drop('A','B').columns]).show(truncate=0)
--- --- ------- -------
|A |B |C |D |
--- --- ------- -------
|123|001|ABC |DEF;DEG|
|256|002|XXX;XXY|DSA |
--- --- ------- -------
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/481493.html
標籤:Python 数据框 阿帕奇火花 pyspark apache-spark-sql
下一篇:如何選擇類別中具有最大值的行?
