Pyspark Dataframe 通过消除空值来合并行

Posted

技术标签:

【中文标题】Pyspark Dataframe 通过消除空值来合并行【英文标题】:Pyspark Dataframe Merge Rows by eliminating null values 【发布时间】:2020-12-21 07:39:26 【问题描述】:

我有一个像这样的 Pyspark 数据框

+-----------+-------+----------+-------+-------+---------+
| ID_PRODUCT| VALUE | TIMESTAMP| SPEED |  CODE | FIRMWARE|
+-----------+-------+----------+-------+-------+---------+
|          3|      1|      null| 124,21|   null|     null|
|          5|      2|      null| 124,23|   null|     null|
|          5|      2|      null| 124,26|   null|     null|
|          6|      4|      null| 124,24|   null|     null|
|          3|      1|      null|   null|   6764|     null|
|          5|      2|      null|   null|   6772|     null|
|          5|      2|      null|   null|   6782|     null|
|          6|      4|      null|   null|   6932|     null|
|          3|      1|      null|   null|   null|        1|
|          5|      2|      null|   null|   null|        1|
|          5|      2|      null|   null|   null|        1|
|          6|      4|      null|   null|   null|        1|
|          3|      1|  17:18:04|   null|   null|     null|
|          5|      2|  18:22:40|   null|   null|     null|
|          5|      2|  18:25:29|   null|   null|     null|
|          6|      4|  18:32:18|   null|   null|     null|
+-----------+-------+----------+-------+-------+---------+

我想合并它的列,它应该看起来像(例如):

+-----------+-------+----------+-------+-------+---------+
| ID_PRODUCT| VALUE | TIMESTAMP| SPEED |  CODE | FIRMWARE|
+-----------+-------+----------+-------+-------+---------+
|          3|      1|  17:18:04| 124,21|   6764|        1|
|          5|      2|  18:22:40| 124,23|   6772|        1|
|          5|      2|  18:25:29| 124,26|   6782|        1|
|          6|      4|  18:32:18| 124,24|   6932|        1|
+-----------+-------+----------+-------+-------+---------+

我尝试使用:

df = df.groupBy('id').agg(*[f.first(x,ignorenulls=True) for x in df.columns])

但是,这只是给我列的第一个值,我需要所有记录。因为对于一个 ID,我有不同的注册时间戳和不同的注册值,我现在正在丢失。

谢谢你的建议

【问题讨论】:

它如何知道要与哪一行合并?为什么要合并 id 为 2 和 6 的行? 这是一个例子,最初的例子是用时间戳来做的 请在您的问题中提供minimal, reproducible example,其中包含解决您的问题所需的所有详细信息。 @mck 我做了更新:) 如果有多个('id_product', 'value')的组合,它怎么知道哪一行对应哪一行,例如对于 (5, 2)? 【参考方案1】:

我不确定这是否是您想要的,但基本上您可以为每个 id 和列创建一个 collect_list,并分解所有结果列表。这样,每个id可以有多个条目。

from functools import reduce
import pyspark.sql.functions as F

df2 = reduce(
    lambda x, y: x.withColumn(y, F.explode_outer(y)),
    df.columns[2:], 
    df.groupBy('id_product', 'value').agg(*[F.collect_list(c).alias(c) for c in df.columns[2:]])
).distinct()

【讨论】:

以上是关于Pyspark Dataframe 通过消除空值来合并行的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PySpark 中的每个分区中回填空值

如何通过避免扫描空值来减少索引扫描

通过列 [PySpark] 连接两个 DataFrame

通过针对 DataFrame 中某个列的不存在的特殊值来生成合成数据样本

pyspark创建空的DataFrame

通过 pyspark.sql.dataframe 将 XML 数据转换为 pandas 数据帧