pyspark считает ненулевые значения для пар в двух столбцах внутри группы - PullRequest
1 голос
/ 10 апреля 2019

У меня есть такие данные

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

и я хочу сгруппировать A, а затем вычислить количество строк, не содержащих нулевое значение. Итак, результат должен быть

A    count  
1      1
2      1
3      0

Не думаю, что это сработает ... да?

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

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Лично я бы использовал вспомогательный столбец, в котором указано, является ли B или C нулевым. Отрицательный результат в этом решении и вернуть 1 или 0. И использовать сумму для этого столбца.

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|
# +---+--------------+
0 голосов
/ 10 апреля 2019

Вы можете удалить строки, содержащие нулевые значения, а затем 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|
+---+-----+
...