首页 > 解决方案 > PySpark GroupBy - 如果没有值,则保留值或 Null

问题描述

我在 PySpark 中编码,并且有一个包含标记及其相关短语的数据框。同一个短语可以出现在多行中,所以我想分组以便只有一行短语,但我想保留具有关联描述符的那个。如果没有描述符,我想保留一行为空。示例数据集:


+------------------------------------+--------+-------+---------+------------+-----------+
|            SENTENCE                | SENT_ID|  TOKEN| TOKEN_ID|     PHRASE | DESCRIPTOR|
+------------------------------------+--------+-------+---------+------------+-----------+
|The handle of the old razor blade...|       1| handle|        2|      handle|       null|
|The handle of the old razor blade...|       1|  razor|        6| razor blade|       null|
|The handle of the old razor blade...|       1|  blade|        7| razor blade|        old|

我希望它看起来像:

+------------------------------------+--------+------------+-----------+
|            SENTENCE                | SENT_ID|     PHRASE | DESCRIPTOR|
+------------------------------------+--------+------------+-----------+
|The handle of the old razor blade...|       1|      handle|       null|
|The handle of the old razor blade...|       1| razor blade|        old|

永远不会出现同一个短语有不同描述的情况。我正在考虑类似 df.groupby('REVIEW_ID','SENT_ID','PHRASE')但不确定如何引入描述符。

标签: pythonapache-sparkpysparkapache-spark-sql

解决方案


使用collect_listorcollect_set函数获取descriptor值。

  • collect_list,在这种情况下collect_set不保留null值,否则用 string 替换null

Example:

df.show()
#+---+----+------+
#| id|name|salary|
#+---+----+------+
#|  1|   a|   100|
#|  1|null|   200|
#|  1|null|   300|
#+---+----+------+

#grouping by id and collecting names

df.groupBy("id").agg(collect_list(col("name")).alias("list")).show()
#+---+----+
#| id|list|
#+---+----+
#|  1| [a]|
#+---+----+

#preserve nulls without duplicates
df.groupBy("id").\
agg(concat_ws(",",collect_list(when(isnull(col("name")),lit('null')).otherwise(col("name")))).alias("list")).\
show()
#+---+-----------+
#| id|       list|
#+---+-----------+
#|  1|a,null,null|
#+---+-----------+

#preserve nulls without duplicates
df.groupBy("id").\
agg(concat_ws(",",collect_set(when(isnull(col("name")),lit('null')).otherwise(col("name")))).alias("list")).\
show()
+---+------+
| id|  list|
+---+------+
|  1|a,null|
+---+------+

推荐阅读