PySpark - 为单个行而不是所有记录设置/删除列

Posted

技术标签:

【中文标题】PySpark - 为单个行而不是所有记录设置/删除列【英文标题】:PySpark - Set/Drop Column for individual rows and not for all records 【发布时间】:2021-12-10 23:02:18 【问题描述】:

我正在寻找一种解决方案,在粘合转换后处理 AWS DynamoDB 中的空值。通常对于为空的数据,当查询完成时,该列不会填充某些字段......但在使用胶水的转换中,该字段设置为空......因此显示为空。

我在网上找到了以下脚本

def drop_null_columns(df):
    import pyspark.sql.functions as F
    null_counts = (
        df.select([F.count(F.when(F.col(c).isNull(), c)).alias(c) for c in df.columns])
        .collect()[0]
        .asDict()
    )
    to_drop = [k for (k, v) in null_counts.items() if v > 0]
    newdf = df.drop(*to_drop)
    return newdf

但是这个脚本会删除所有甚至有 1 个 null 的列,例如下面的示例。

之前

C1  | C2  | C3
------------
123 |null | 12
123 |15   | 12
123 |15   | 12
123 |12   | 12

之后

C1  | C3
------------
123 | 12
123 | 12
123 | 12
123 | 12

我希望有一个存在 NULL 的行,只是空白/空。

之前

C1  | C2  | C3
------------
123 |null | 12
123 |15   | 12
123 |15   | 12
123 |12   | 12

之后

C1  | C2  | C3
------------
123 |     | 12
123 |15   | 12
123 |15   | 12
123 |12   | 12

【问题讨论】:

试试df.na.fill('') 这能回答你的问题吗? Replace null with empty string when writing Spark dataframe 有问题的类型是数组还是列表? 【参考方案1】:

Spark自动推断C2字段是long类型,所以替换时需要指定long类型的值。如果推断C2字段的类型为string,则可以使用df.fillna('')

newdf = df.fillna(0)

【讨论】:

如果类型是数组或者列表呢? 目前fillna仅支持intfloatbooleanstring

以上是关于PySpark - 为单个行而不是所有记录设置/删除列的主要内容,如果未能解决你的问题,请参考以下文章

如何设置整行而不是所有单元格的样式

将重复记录合并到 pyspark 数据框中的单个记录中

使用 Pyspark 使用 Spark 读取巨大 Json 文件的第一行

Spark数据框左连接应在右侧添加默认行而不是null的连接

mysql update 正在更新所有行而不是一个

AG-Grid:updateRowData(update: ItemsArray) 影响所有行而不是选定行