PySpark按条件计算值

mar*_*tin 8 python apache-spark pyspark

我有一个DataFrame,这里有一个片段:

[['u1', 1], ['u2', 0]]
Run Code Online (Sandbox Code Playgroud)

基本上是一个名为的字符串字段f,对于第二个元素(is_fav)为1或0 .

我需要做的是分组第一个字段并计算1和0的出现次数.我希望做类似的事情

num_fav = count((col("is_fav") == 1)).alias("num_fav")

num_nonfav = count((col("is_fav") == 0)).alias("num_nonfav")

df.groupBy("f").agg(num_fav, num_nonfav)
Run Code Online (Sandbox Code Playgroud)

它不能正常工作,我在两种情况下都得到相同的结果,这相当于组中项目的计数,因此过滤器(无论是1还是0)似乎被忽略.这取决于count工作原理吗?

zer*_*323 14

这里没有过滤器.双方col("is_fav") == 1col("is_fav") == 0)都只是布尔表达式,并count只要不真正关心他们的价值,因为它被定义.

有很多方法可以解决这个问题,例如使用简单的方法sum:

from pyspark.sql.functions import sum, abs

gpd = df.groupBy("f")
gpd.agg(
    sum("is_fav").alias("fv"),
    (count("is_fav") - sum("is_fav")).alias("nfv")
)
Run Code Online (Sandbox Code Playgroud)

或者使被忽略的值undefined(aka NULL):

exprs = [
    count(when(col("is_fav") == x, True)).alias(c)
    for (x, c) in [(1, "fv"), (0, "nfv")]
]
gpd.agg(*exprs)
Run Code Online (Sandbox Code Playgroud)

  • 总而言之,我在第一个解决方案中收到 TypeError: unsupported operand type(s) for +: 'int' and 'str' 。我确定“is_fav”列包含 IntegerType 所以我不明白? (2认同)