删除整列为空的所有列

数据挖掘 Python 数据清理 阿帕奇火花 pyspark
2022-03-01 19:20:45

我有一个非常脏的 csv,其中有几列只有空值。

我想删除它们。我正在尝试选择列中空值计数不等于行数的所有列。

clean_df = bucketed_df.select([c for c in bucketed_df.columns if count(when(isnull(c), c)) not bucketed_df.count()])

但是,我收到此错误:

SyntaxError: invalid syntax
  File "<command-2213215314329625>", line 1
    clean_df = bucketed_df.select([c for c in bucketed_df.columns if count(when(isnull(c), c)) not bucketed_df.count()])
                                                                                                             ^
SyntaxError: invalid syntax

如果有人可以帮助我摆脱这些脏列,那就太好了。

3个回答

接受的答案将起作用,但会df.count()针对每一列运行,这对于大量列来说是相当繁重的。在列表理解之前计算一次,并为自己节省大量时间:

def drop_null_columns(df):
  
    """
    This function drops columns containing all null values.
    :param df: A PySpark DataFrame
    """
    _df_length = df.count()
    null_counts = df.select([sqlf.count(sqlf.when(sqlf.col(c).isNull(), c)).alias(c) for c in df.columns]).collect()[0].asDict()
    to_drop = [k for k, v in null_counts.items() if v >= _df_length]
    df = df.drop(*to_drop)
    
    return df

[更新]:刚刚意识到它是关于 pyspark 的!

还是很简单!一个具体的例子(从这个答案中大量借用的想法):

创建虚拟数据集

import pandas as pd
import numpy as np 
import pyspark.sql.functions as sqlf

main= pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))

main["E"]= np.NAN
main["F"]= np.NAN

df = sqlContext.createDataFrame(main)

删除 Null 列的函数

def drop_null_columns(df):
  
    """
    This function drops columns containing all null values.
    :param df: A PySpark DataFrame
    """
    
    null_counts = df.select([sqlf.count(sqlf.when(sqlf.col(c).isNull(), c)).alias(c) for c in df.columns]).collect()[0].asDict()
    to_drop = [k for k, v in null_counts.items() if v >= df.count()]
    df = df.drop(*to_drop)
    
    return df

结果

df_dropped = drop_null_columns(df)

您好,我认为这些行可能会有所帮助:我的案例并未准确回答原始问题。如果我们只需要保留至少有一个检查列的行不为空,那么使用这个:

from pyspark.sql import functions as F
from operator import or_
from functools import reduce

inspected = df.columns
df = df.where(reduce(or_, (F.col(c).isNotNull() for c in inspected ), F.lit(False)))