Python 如何在这个drop nulls函数中避免collect()?提高性能的(其他)方法是什么?

Python 如何在这个drop nulls函数中避免collect()?提高性能的(其他)方法是什么?,python,performance,pyspark,collect,coding-efficiency,Python,Performance,Pyspark,Collect,Coding Efficiency,我有一个函数,用于计算每列中所有不同的值。我有一个非常大的数据集,其中有时包含没有数据的列。然后我删除这些列,并返回一个print语句,告诉我哪些列已被删除。我的数据的大小将来可能会增加,因此我希望避免使用collect(),因为我不想收集到驱动程序。在这种情况下,我如何避免它?你能想到这个功能有什么改进吗?非常感谢您的建议/示例 def dropNullColumns(df): # A set of all the null values you can encounter n

我有一个函数,用于计算每列中所有不同的值。我有一个非常大的数据集,其中有时包含没有数据的列。然后我删除这些列,并返回一个print语句,告诉我哪些列已被删除。我的数据的大小将来可能会增加,因此我希望避免使用collect(),因为我不想收集到驱动程序。在这种情况下,我如何避免它?你能想到这个功能有什么改进吗?非常感谢您的建议/示例

def dropNullColumns(df):
    # A set of all the null values you can encounter
    null_set = {"none", "null" , "nan"}
    # Iterate over each column in the DF
    for col in df.columns:
        # Get the distinct values of the column
        unique_val = df.select(col).distinct().collect()[0][0]
        # See whether the unique value is only none/nan or null
        if str(unique_val).lower() in null_set:
            print("Dropping " + col + " because of all null values.")
            df = df.drop(col)
    return(df)

df = dropNullColumns(df)

这套功能是否适合需要

您可以稍后筛选百分比==1.0

def check_percent_na(sdf: DataFrame, col_name: str, customized_na_list=['', "null", "nan"]) -> Tuple:
    total_num: int = sdf.count()
    if dict(sdf.dtypes)[col_name] == "string":
        na_num: int = sdf.filter((sf.col(col_name).isNull()) | (sf.col(col_name).isin(customized_na_list))).count()
    else:
        na_num: int = sdf.filter(sf.col(col_name).isNull()).count()
    return col_name, na_num/total_num

def check_percent_na_dataframe(sdf: DataFrame) -> List:
    return list(map(lambda x: check_percent_na(sdf=sdf, col_name=x), sdf.columns))

我发布的函数实际上有很多缺点。不仅如此,它还使用collect()。它也不是非常健壮,并且会删除实际上不应该删除的列。请考虑以下方法:

rows = [(None, 18, None, None),
            (1, None, None, None),
            (1, 9, 4.0, None),
            (None, 0, 0., None)]

schema = "a: int, b: int, c: float, d:int"
df = spark.createDataFrame(data=rows, schema=schema)

def get_null_column_names(df):
    column_names = []

    for col_name in df.columns:

        min_ = df.select(F.min(col_name)).first()[0]
        max_ = df.select(F.max(col_name)).first()[0]

        if min_ is None and max_ is None:
            column_names.append(col_name)

    return column_names

null_columns = get_null_column_names(df)

def drop_column(null_columns, df):
  for column_ in drop_these_columns:
    df = df.drop(column_)
    return df

df = drop_column(null_columns, df)
df.show()
产生以下输出: