ChatGPT解决这个技术问题 Extra ChatGPT

如何有效地查找 PySpark 数据框中每一列的 Null 和 Nan 值的计数?

import numpy as np

data = [
    (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")),
]
df = spark.createDataFrame(data, ("session", "timestamp1", "id2"))

预期产出

每列的 nan/null 计数的数据框

注意:我在堆栈溢出中发现的前面的问题只检查 null 而不是 nan。这就是为什么我创建了一个新问题。

我知道我可以在 Spark 中使用 isnull() 函数来查找 Spark 列中 Null 值的数量,但是如何在 Spark 数据框中找到 Nan 值?

scala 有什么解决方案吗?

u
user8183279

您可以使用显示的方法 here 并将 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|
+-------+----------+---+

isNullisnan。这两个链接将对您有所帮助。 "isnan()" 是 pysparq.sql.function 包的一个函数,所以你必须设置你想使用哪一列作为函数的参数。 "isNull()" 属于 pyspark.sql.Column 包,所以你要做的就是 "yourColumn.isNull()"
我收到这个 df.select([count(when(isnan(c) | col(c).isNull(), c)).alias(c) for c in df.columns]).show() 的错误- 有没有我需要导入的库。我得到的错误是简单表达式的非法开始。
此解决方案不适用于时间戳列
@EricBellet 对于您可以使用的时间戳列 df.dtypesdf.select([f.count(f.when(f.isnan(c), c)).alias(c) for c, t in df.dtypes if t != "timestamp"]).show()
scala 等价物:df.select(df.columns.map(c => count(when(isnan(col(c)), c)).alias(c)):_*)
V
Vamsi Krishna

对于 pyspark 的数据框中的空值

Dict_Null = {col:df.filter(df[col].isNull()).count() for col in df.columns}
Dict_Null

# The output in dict where key is column name and value is null values in that column

{'#': 0,
 'Name': 0,
 'Type 1': 0,
 'Type 2': 386,
 'Total': 0,
 'HP': 0,
 'Attack': 0,
 'Defense': 0,
 'Sp_Atk': 0,
 'Sp_Def': 0,
 'Speed': 0,
 'Generation': 0,
 'Legendary': 0}

g
gench

为确保 stringdatetimestamp 列不会失败:

import pyspark.sql.functions as F
def count_missings(spark_df,sort=True):
    """
    Counts number of nulls and nans in each column
    """
    df = spark_df.select([F.count(F.when(F.isnan(c) | F.isnull(c), c)).alias(c) for (c,c_type) in spark_df.dtypes if c_type not in ('timestamp', 'string', 'date')]).toPandas()

    if len(df) == 0:
        print("There are no any missing values!")
        return None

    if sort:
        return df.rename(index={0: 'count'}).T.sort_values("count",ascending=False)

    return df

如果您想查看按降序排列的 nan 和 null 数排序的列:

count_missings(spark_df)

# | Col_A | 10 |
# | Col_C | 2  |
# | Col_B | 1  | 

如果您不想订购并将它们视为单行:

count_missings(spark_df, False)
# | Col_A | Col_B | Col_C |
# |  10   |   1   |   2   |

对于大型数据集,此函数的计算成本很高。
你为什么这么认为?
将“布尔”和“二进制”添加到您的非排除列表中
危险,因为在任何排除类型中都会默默地忽略 Null
M
Marioanzas

这是我的一个班轮。这里'c'是列的名称

from pyspark.sql.functions import isnan, when, count, col, isNull
    
df.select('c').withColumn('isNull_c',F.col('c').isNull()).where('isNull_c = True').count()

K
Kubra Tas

已经提供的方法的替代方法是像这样简单地过滤列

import pyspark.sql.functions as F
df = df.where(F.col('columnNameHere').isNull())

这有一个额外的好处,即您不必添加另一列来进行过滤,并且它在更大的数据集上速度很快。


覆盖 df,也许这不是故意的。 OP 要求计数,对于 x dframe 和 colname 字符串可能应该是 x.where(col(colname).isNull()).count()
E
Eric Bellet

我更喜欢这个解决方案:

df = spark.table(selected_table).filter(condition)

counter = df.count()

df = df.select([(counter - count(c)).alias(c) for c in df.columns])

i
ijoseph
from pyspark.sql import DataFrame
import pyspark.sql.functions as fn

# compatiable with fn.isnan. Sourced from
# https://github.com/apache/spark/blob/13fd272cd3/python/pyspark/sql/functions.py#L4818-L4836
NUMERIC_DTYPES = (
    'decimal',
    'double',
    'float',
    'int',
    'bigint',
    'smallilnt',
    'tinyint',
)


def count_nulls(df: DataFrame) -> DataFrame:
    isnan_compat_cols = {c for (c, t) in df.dtypes if any(t.startswith(num_dtype) for num_dtype in NUMERIC_DTYPES)}

    return df.select(
        [fn.count(fn.when(fn.isnan(c) | fn.isnull(c), c)).alias(c) for c in isnan_compat_cols]
        + [fn.count(fn.when(fn.isnull(c), c)).alias(c) for c in set(df.columns) - isnan_compat_cols]
    )

根据 gench 和 user8183279 的答案构建,但仅通过 isnull 检查不可能 isnan 的列,而不是忽略它们。

pyspark.sql.functions seemed to have the only documentation I could really find enumerating these names — if others know of some public docs I'd be delighted 的源代码。


D
DivineCoder

如果您正在编写 spark sql,那么以下内容也将用于查找空值并随后进行计数。

spark.sql('select * from table where isNULL(column_value)')


R
Rajesh Ramachander

还有另一种选择(根据上述 Vamsi Krishna 的解决方案进行了改进):

def check_for_null_or_nan(df):
    null_or_nan = lambda x: isnan(x) | isnull(x)
    func = lambda x: df.filter(null_or_nan(x)).count()
    print(*[f'{i} has {func(i)} nans/nulls' for i in df.columns if func(i)!=0],sep='\n')

check_for_null_or_nan(df)

id2 有 5 个 nans/null