【问题标题】:How do I replace a string value with a NULL in PySpark?如何在 PySpark 中用 NULL 替换字符串值?
【发布时间】:2016-08-22 05:07:44
【问题描述】:

我想做这样的事情:

df.replace('empty-value', None, 'NAME')

基本上,我想用 NULL 替换一些值。但它不接受此函数中的 None 。我该怎么做?

【问题讨论】:

    标签: apache-spark dataframe null pyspark


    【解决方案1】:

    您可以将when 子句与NULL 文字和类型转换组合如下:

    from pyspark.sql.functions import when, lit, col
    
    df = sc.parallelize([(1, "foo"), (2, "bar")]).toDF(["x", "y"])
    
    def replace(column, value):
        return when(column != value, column).otherwise(lit(None))
    
    df.withColumn("y", replace(col("y"), "bar")).show()
    ## +---+----+
    ## |  x|   y|
    ## +---+----+
    ## |  1| foo|
    ## |  2|null|
    ## +---+----+
    

    它没有引入BatchPythonEvaluation,因此应该比使用 UDF 更有效。

    【讨论】:

    • 优秀,对于大型数据集效率更高。
    • @cftarnas 是,Python UDF 的 serde 开销比较高。
    • @zero323 你实际上并不需要otherwise() 部分 - 默认情况下when() 将返回null
    • 能否请您展示如何使用嵌套字段来做到这一点?
    • @zero323 否则,我尝试返回 None 而不是 lit(None) 并且结果是相同的。你能解释一下你为什么使用 lit 吗?
    【解决方案2】:

    这将在您的name 列中将empty-value 替换为None

    from pyspark.sql.functions import udf
    from pyspark.sql.types import StringType
    
    
    df = sc.parallelize([(1, "empty-value"), (2, "something else")]).toDF(["key", "name"])
    new_column_udf = udf(lambda name: None if name == "empty-value" else name, StringType())
    new_df = df.withColumn("name", new_column_udf(df.name))
    new_df.collect()
    

    输出:

    [Row(key=1, name=None), Row(key=2, name=u'something else')]
    

    通过使用旧名称作为withColumn 中的第一个参数,它实际上将旧的name 列替换为UDF 输出生成的新列。

    【讨论】:

    • 我没想过尝试UDF,这似乎是要走的路
    • 如果您使用本机 Spark 函数而不是 UDF,您的代码将运行得更快 - 请参阅其他答案。 (这就是为什么他们的赞成票比接受的答案多)
    【解决方案3】:

    最好的替代方法是将whenNULL 结合使用。示例:

    from pyspark.sql.functions import when, lit, col
    
    df= df.withColumn('foo', when(col('foo') != 'empty-value',col('foo)))
    

    如果您想将多个值替换为 null,您可以在 when 条件内使用 | 或强大的 create_map 函数。

    需要注意的是,最糟糕的方法是使用 UDF 来解决它。之所以如此,是因为 udf 为您的代码提供了强大的多功能性,但会带来对性能的巨大损失

    【讨论】:

      【解决方案4】:

      您也可以简单地将字典用于replace 的第一个参数。我试过了,这似乎接受None 作为参数。

      df = df.replace({'empty-value':None}, subset=['NAME'])
      

      请注意,您的 'empty-value' needs to be hashable

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-04
        • 2021-04-04
        • 2021-11-17
        • 2020-06-18
        • 1970-01-01
        • 2016-01-22
        • 2014-03-04
        相关资源
        最近更新 更多