Как можно избежать collect () в этой функции удаления нулей? Каким может быть (дополнительный) способ (ы) повышения производительности? - PullRequest
0 голосов
/ 28 января 2020

У меня есть функция, которую я использую для подсчета всех различных значений в каждом столбце. У меня очень большой набор данных, который иногда содержит столбцы без данных. Затем я удаляю эти столбцы и возвращаю инструкцию 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)

Ответы [ 2 ]

0 голосов
/ 11 февраля 2020

Функция, которую я разместил, на самом деле имеет много недостатков. Он не только использует метод 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()

Получает следующий вывод:

enter image description here

0 голосов
/ 28 января 2020

соответствует ли этот набор функций нужным?

вы можете позже фильтровать проценты == 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))
...