spark条件和函数返回null

vjrehmav  于 2021-07-09  发布在  Spark
关注(0)|答案(2)|浏览(401)

我解释了spark sum函数可以使用字符串列名。然而,我看到不同的结果时使用 column name 或者 column object .

schema = ["department", "employee", "knwos_ops", "developer"]
data = [("frontend", "john", 0, 1,), ("frontend", "jenny", 1, 1,), ("frontend", "michael", 0, 1,)]
input_df = spark.createDataFrame(data, schema=schema)
input_df.show(5, False)

+----------+--------+---------+---------+
|department|employee|knwos_ops|developer|
+----------+--------+---------+---------+
|frontend  |john    |0        |1        |
|frontend  |jenny   |1        |1        |
|frontend  |michael |0        |1        |
+----------+--------+---------+---------+

input_df \
    .groupBy(*["department"]) \
    .agg( \
            f.sum("developer").alias("dev"), \
            f.sum(f.when(f.col("knwos_ops") == 1, "developer")).alias("devops"), \
            f.sum("knwos_ops").alias("ops"),
    ).show(5, False)

+----------+---+------+---+
|department|dev|devops|ops|
+----------+---+------+---+
|frontend  |3  |null  |1  |
+----------+---+------+---+

input_df \
    .groupBy(*["department"]) \
    .agg( \
            f.sum("developer").alias("developer"), \
            f.sum(f.when(f.col("knwos_ops") == 1, f.col("developer"))).alias("devops"), \
            f.sum("knwos_ops").alias("ops"),
    ).show(5, False)

+----------+---+------+---+
|department|dev|devops|ops|
+----------+---+------+---+
|frontend  |3  |1     |1  |
+----------+---+------+---+

我对函数的理解 sum 以及 when 正在跟踪,
功能 when 如果条件匹配则返回值,否则返回null。
功能 sum 使用string类型的列名或column类型的列名。
基于此,在第一个聚合示例中 when 函数应返回列 developer 函数应使用的字符串名称 sum 汇总并返回2。但是它返回null。
为什么spark无法识别 developer 是Dataframe的一列。有人能帮我理解这背后的文档吗?
更新谢谢你的好意回复。正如我在第二次聚合中所做的,我有办法解决这个问题。我在寻找这种行为背后的解释,以及有人指出我对这种行为的理解的差距 sum .
让我换个说法。如果sum函数获取字符串作为参数,它将尝试在Dataframe中查找同名的列


#### sum function receives string as argument, and finds the column and does the sum

input_df.agg(f.sum("developer")).show(5, False)
+--------------+
|sum(developer)|
+--------------+
|3             |
+--------------+

#### sum function receives string as argument, and finds the column and does the sum. Field type is string so it return null

input_df.agg(f.sum("employee")).show(5, False)
+--------------+
|sum(developer)|
+--------------+
|null          |
+--------------+

#### sum function receives string as argument, and does not find the column and throws error

input_df.agg(f.sum("manager")).show(5, False)
Py4JJavaError: An error occurred while calling o839.agg.
: org.apache.spark.sql.AnalysisException: cannot resolve '`manager`' given input columns: [department, employee, knwos_ops, developer];

基于以上代码片段,我期望函数 when 返回字符串 developer 我希望这个功能 sum 将使用该字符串从该字符串解析列并进行聚合。

myzjeezk

myzjeezk1#

您可能需要执行以下操作:

input_df \
    .groupBy(*["department"]) \
    .agg( \
            f.sum("developer").alias("developer"), \
            f.expr("SUM(CASE WHEN knwos_ops = 1 AND developer = 1 THEN 1 ELSE 0) AS devops"), \
            f.sum("knwos_ops").alias("ops"),
    ).show(5, False)
xienkqul

xienkqul2#

when 与其他sparksql函数有点不同。如果在 then / otherwise 语句,它将被解释为字符串文本而不是列。
例如,字符串文本的一个可能的用例可能是

F.when(F.col('size') > 10, 'large').otherwise('small')

spark会解释 large 以及 small 作为字符串文本而不是列。
因此,在您的用例中,您总结了 'developer' 字符串,返回null,因为字符串不能求和。
由于这种模糊性,有必要具体说明 F.col 澄清您想要一个列作为 then / otherwise 声明。

相关问题