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

43

我想做类似这样的事情:

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

基本上,我想用NULL替换一些值,但它不接受None作为参数。我该怎么做?

5个回答

78

您可以按如下方式将 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相比应该更高效。


7
非常好,对于大型数据集更高效。 - cftarnas
@cftarnas 是的,Python UDFs 具有相对较高的序列化开销。 - zero323
10
@zero323,实际上你不需要otherwise()部分 - when()默认会返回null - pault
请问您能演示一下如何使用嵌套字段完成这个操作吗? - Ébe Isaac
@zero323 在其他情况下,我尝试返回None而不是lit(None),结果是相同的。您能否请解释一下为什么要使用lit? - ravi malhotra
@zero323 什么时候可以直接提到 .otherwise(lit(null)) 对吧? - BdEngineer

9

这将在您的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中使用旧名称作为第一个参数,实际上用UDF的输出生成的新列替换了旧的name列。

我没有想过尝试UDFs,这似乎是正确的方法。 - talloaktrees
2
如果使用本地Spark函数而不是UDF,您的代码将运行得更快-请参见其他答案。(这就是为什么它们比被接受的答案获得更多的赞同) - RobinL

9

你也可以直接使用字典作为 replace 函数的第一个参数。我已经尝试过,似乎这个函数可以接受 None 作为参数。

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

请注意,您的'empty-value'需要是可哈希的。点击了解更多

5
最佳的替代方法是使用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提供了代码的极大灵活性,但会带来巨大的性能损失


0
这也可以工作:
df5 = df.replace(str('空值'), None)

1
你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人能够确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接