如何在PySpark中用NULL替换字符串值?

tal*_*ees 14 null dataframe apache-spark pyspark

我想做这样的事情:

df.replace('empty-value', None, 'NAME')
Run Code Online (Sandbox Code Playgroud)

基本上,我想用NULL替换一些值.但是在这个函数中它不接受None.我怎样才能做到这一点?

zer*_*323 29

您可以将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|
## +---+----+
Run Code Online (Sandbox Code Playgroud)

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

  • 优秀,对大型数据集更有效. (4认同)
  • @ zero323你实际上并不需要`otherwise()`part - `when()`默认会返回`null`. (3认同)

Dan*_*nai 8

这将在您的列中替换empty-value为:Nonename

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()
Run Code Online (Sandbox Code Playgroud)

输出:

[Row(key=1, name=None), Row(key=2, name=u'something else')]
Run Code Online (Sandbox Code Playgroud)

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

  • 如果您使用本机 Spark 函数而不是 UDF,您的代码将运行得更快 - 请参阅其他答案。(这就是为什么他们的赞成票比接受的答案多) (2认同)

小智 5

最好的选择是将 awhen与 a 结合使用NULL。例子:

from pyspark.sql.functions import when, lit, col

df= df.withColumn('foo', when(col('foo') != 'empty-value',col('foo)))
Run Code Online (Sandbox Code Playgroud)

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

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


Wil*_*lem 5

您也可以简单地将 dict 用于replace. 我试过了,这似乎可以None作为一个论点。

df = df.replace({'empty-value':None}, subset=['NAME'])
Run Code Online (Sandbox Code Playgroud)

请注意,您'empty-value' 需要是可散列的