Apache spark PySpark:withColumn()具有两个条件和三个结果

Apache spark PySpark:withColumn()具有两个条件和三个结果,apache-spark,hive,pyspark,apache-spark-sql,hiveql,Apache Spark,Hive,Pyspark,Apache Spark Sql,Hiveql,我和Spark和Pypark一起工作。我试图实现与以下伪代码等效的结果: df=df.withColumn('new_column', 如果FROUT1==FROUT2,则为1,否则为0。如果FROUT1为NULL或FROUT2为NULL,则为3。) 我试图在PySpark中实现这一点,但我不确定语法。有什么建议吗?我查看了expr(),但无法让它工作 请注意,df是一个pyspark.sql.dataframe.dataframe您需要使用如下udf from pyspark.sql.typ

我和Spark和Pypark一起工作。我试图实现与以下伪代码等效的结果:

df=df.withColumn('new_column',
如果FROUT1==FROUT2,则为1,否则为0。如果FROUT1为NULL或FROUT2为NULL,则为3。)
我试图在PySpark中实现这一点,但我不确定语法。有什么建议吗?我查看了
expr()
,但无法让它工作


请注意,
df
是一个
pyspark.sql.dataframe.dataframe

您需要使用如下udf

from pyspark.sql.types import IntegerType
from pyspark.sql.functions import udf

def func(fruit1, fruit2):
    if fruit1 == None or fruit2 == None:
        return 3
    if fruit1 == fruit2:
        return 1
    return 0

func_udf = udf(func, IntegerType())
df = df.withColumn('new_column',func_udf(df['fruit1'], df['fruit2']))

有几种有效的方法来实现这一点。让我们从所需的导入开始:

from pyspark.sql.functions import col, expr, when
您可以在expr内使用配置单元
IF
函数:

new_column_1 = expr(
    """IF(fruit1 IS NULL OR fruit2 IS NULL, 3, IF(fruit1 = fruit2, 1, 0))"""
)
+
否则

new_column_2 = when(
    col("fruit1").isNull() | col("fruit2").isNull(), 3
).when(col("fruit1") == col("fruit2"), 1).otherwise(0)
最后,您可以使用以下技巧:

from pyspark.sql.functions import coalesce, lit

new_column_3 = coalesce((col("fruit1") == col("fruit2")).cast("int"), lit(3))
使用示例数据:

df = sc.parallelize([
    ("orange", "apple"), ("kiwi", None), (None, "banana"), 
    ("mango", "mango"), (None, None)
]).toDF(["fruit1", "fruit2"])
您可以按如下方式使用它:

(df
    .withColumn("new_column_1", new_column_1)
    .withColumn("new_column_2", new_column_2)
    .withColumn("new_column_3", new_column_3))
结果是:

+------+------+------------+------------+------------+
|结果1 |结果2 |新|列| 1 |新|列| 2 |新|列| 3|
+------+------+------------+------------+------------+
|橙色|苹果| 0 | 0 | 0|
|猕猴桃|空| 3 | 3 | 3|
|空|香蕉| 3 | 3 | 3|
|芒果|芒果| 1 | 1 | 1|
|空|空| 3 | 3 | 3|
+------+------+------------+------------+------------+

pyspark中的withColumn函数使您能够使用条件创建一个新变量,添加whenothers函数,这样您就有了一个正常工作的if-then-else结构。 对于所有这些,您需要导入sparksql函数,因为您将看到,如果没有col()函数,下面的代码将无法工作。 在第一位中,我们声明了一个新列-“new column”,然后给出when函数中包含的条件(即,fruth1==fruth2),然后如果条件为true,则给出1;如果条件为false,则控件转到否则,否则它将处理第二个条件(fruth1或fruth2为Null),并使用isNull()函数,如果返回true 3,如果返回false,则再次检查否则,并给出0作为答案

从pyspark.sql导入函数为F
df=df.withColumn('new_column',
F.when(F.col('fruit1')==F.col('fruit2'),1)
。否则(F.when((F.col('grout1').isNull())|(F.col('grout2').isNull()),3))
。否则(0))

我从这个解决方案中得到了几个错误,@David。第一个问题通过pyspark.sql.types import StringType中的
解决。第二个是:
TypeError:“int”对象不可调用
,我不确定如何解决。请注意,
df
是一个
pyspark.sql.dataframe.dataframe
@user2205916,我有几个输入错误。在
def func(…
行中,我有
水果1
(带空格)而不是
foult1
。在开始的
func_udf=…
行中,我有
StringType
而不是
IntegerType
。用更新后的代码尝试一下,如果仍然有问题,请告诉我。我会收到相同的错误消息。此外,我认为
df=…
末尾缺少一个paren,这是另一个输入错误,从第二位到最后一位ne应该是
func\u udf=udf(func,IntegerType())
必须运行,但这很接近(可以承受打字错误)。如果它仍然不起作用,请确保在spark 2.2+中没有类似情况,函数“col”对我不起作用。直接使用不带引号的列名可以起作用。例如:new\u column\u 1=expr(“col\u 1+int(col_2/15)“你能解释一下你的代码吗?这样新来的人就能理解你的代码了done@Nidhi,如果
grout1
grout2
来自不同的数据帧,是否可以执行类似的操作?