Как эффективно найти количество значений Null и Nan для каждого столбца в кадре данных PySpark?

import numpy as np

df = spark.createDataFrame(
    [(1, 1, None), (1, 2, float(5)), (1, 3, np.nan), (1, 4, None), (1, 5, float(10)), (1, 6, float('nan')), (1, 6, float('nan'))],
    ('session', "timestamp1", "id2"))

Ожидаемый результат

dataframe со счетом nan/null для каждого столбца

Примечание. Предыдущие вопросы, которые я нашел в переполнении стека, проверяют только на null & not nan. Вот почему я создал новый вопрос.

Я знаю, что могу использовать функцию isnull() в искры, чтобы найти число значений Null в столбце Spark, но как найти значения Nan в Spark dataframe?

Ответ 1

Вы можете использовать метод, показанный здесь, и заменить isNull на isnan:

from pyspark.sql.functions import isnan, when, count, col

df.select([count(when(isnan(c), c)).alias(c) for c in df.columns]).show()
+-------+----------+---+
|session|timestamp1|id2|
+-------+----------+---+
|      0|         0|  3|
+-------+----------+---+

или же

df.select([count(when(isnan(c) | col(c).isNull(), c)).alias(c) for c in df.columns]).show()
+-------+----------+---+
|session|timestamp1|id2|
+-------+----------+---+
|      0|         0|  5|
+-------+----------+---+

Ответ 2

Вы можете создать UDF для ckeck как null и NaN и вернуть значение boolean для фильтрации

Код - код scala, который вы можете преобразовать в python.

val isNaN = udf((value : Float) => {
   if (value.equals(Float.NaN) || value == null) true else false }) 

val result = data.filter(isNaN(data("column2"))).count()

Надеюсь это поможет !

Ответ 3

Мои значения NULL были STRING - приведенный ниже код возвращает пару ключ-значение, где ключ - это имя столбца, а значение - счетчик NULL.

from pyspark.sql import functions as F

countLst =[df.where(F.col(c).like("%NULL%")).count() for c in df.columns]
[{k: v} for k, v in zip(df.columns, countLst)]

NUll count, пример вывода:

[{'COL1': 0},
 {'COL2': 266},
 {'COL3': 520},
 {'COL4': 3663},
 {'COL5': 518},
 {'COL6': 0}]