pyspark计数不是组中两列中对的空值

时间:2019-04-10 18:49:08

标签: python group-by count pyspark null

我有一些这样的数据

A    B    C
1   Null  3
1   2     4
2   Null  6
2   2    Null
2   1    2
3   Null 4

,我想对A进行分组,然后计算不包含Null值的行数。因此,结果应为

A    count  
1      1
2      1
3      0

我认为这行不通...,对吗?

df.groupby('A').agg(count('B','C'))

2 个答案:

答案 0 :(得分:1)

就个人而言,我将使用辅助列说明B或C是否为Null。此解决方案中的结果为负,并返回1或0。为此列使用sum。

from pyspark.sql.functions import sum, when
# ...
df.withColumn("isNotNull", when(df.B.isNull() | df.C.isNull(), 0).otherwise(1))\
    .groupBy("A").agg(sum("isNotNull"))

演示:

df.show()
# +---+----+----+                                                                 
# | _1|  _2|  _3|
# +---+----+----+
# |  1|null|   3|
# |  1|   2|   4|
# |  2|null|   6|
# |  2|   2|null|
# |  2|   1|   2|
# |  3|null|   4|
# +---+----+----+

df.withColumn("isNotNull", when(df._2.isNull() | df._3.isNull(), 0).otherwise(1)).show()
# +---+----+----+---------+
# | _1|  _2|  _3|isNotNull|
# +---+----+----+---------+
# |  1|null|   3|        0|
# |  1|   2|   4|        1|
# |  2|null|   6|        0|
# |  2|   2|null|        0|
# |  2|   1|   2|        1|
# |  3|null|   4|        0|
# +---+----+----+---------+

df.withColumn("isNotNull", when(df._2.isNull() | df._3.isNull(), 0).otherwise(1))\
  .groupBy("_1").agg(sum("isNotNull")).show()
# +---+--------------+
# | _1|sum(isNotNull)|
# +---+--------------+
# |  1|             1|
# |  3|             0|
# |  2|             1|
# +---+--------------+

答案 1 :(得分:0)

您可以删除包含空值的行,然后删除groupby + count

df.select('A').dropDuplicates().join(
    df.dropna(how='any').groupby('A').count(), on=['A'], how='left'
).show()
+---+-----+
|  A|count|
+---+-----+
|  1|    1|
|  3| null|
|  2|    1|
+---+-----+

如果您不想进行联接,请创建另一列以指示B列或C列是否为空:

import pyspark.sql.functions as f
df.selectExpr('*', 
    'case when B is not null and C is not null then 1 else 0 end as D'
).groupby('A').agg(f.sum('D').alias('count')).show()
+---+-----+
|  A|count|
+---+-----+
|  1|    1|
|  3|    0|
|  2|    1|
+---+-----+