Python 如何在这个drop nulls函数中避免collect()?提高性能的(其他)方法是什么?
我有一个函数,用于计算每列中所有不同的值。我有一个非常大的数据集,其中有时包含没有数据的列。然后我删除这些列,并返回一个print语句,告诉我哪些列已被删除。我的数据的大小将来可能会增加,因此我希望避免使用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
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()
产生以下输出: