如果spark数据帧的特定列中的所有条目都为null,则删除

时间:2017-08-11 07:52:29

标签: python apache-spark pyspark

使用Pyspark,如何选择/保留包含非空值的DataFrame的所有;或者等效地删除所有不包含数据的列。

编辑:根据Suresh请求,

for column in media.columns:
    if media.select(media[column]).distinct().count() == 1:
        media = media.drop(media[column])

这里我假设如果count是1,那么它应该是Nan。但我想检查一下是否是楠。如果还有其他内置火花功能,请告诉我。

9 个答案:

答案 0 :(得分:1)

我试过了。我知道它是否有效,

{{1}}

答案 1 :(得分:1)

这是我在管道中删除空列的功能。 希望对您有帮助!

# Function to drop the empty columns of a DF
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)

答案 2 :(得分:1)

这是一个效率更高的解决方案,它不需要循环遍历列。当您有许多列时,它会更快。我在具有800列的数据帧上测试了其他方法,该过程耗时17分钟。在我对同一数据集的测试中,以下方法仅需1分钟。

def drop_fully_null_columns(df, but_keep_these=[]):
    """Drops DataFrame columns that are fully null
    (i.e. the maximum value is null)

    Arguments:
        df {spark DataFrame} -- spark dataframe
        but_keep_these {list} -- list of columns to keep without checking for nulls

    Returns:
        spark DataFrame -- dataframe with fully null columns removed
    """

    # skip checking some columns
    cols_to_check = [col for col in df.columns if col not in but_keep_these]
    if len(cols_to_check) > 0:
        # drop columns for which the max is None
        rows_with_data = df.select(*cols_to_check).groupby().agg(*[F.max(c).alias(c) for c in cols_to_check]).take(1)[0]
        cols_to_drop = [c for c, const in rows_with_data.asDict().items() if const == None]
        new_df = df.drop(*cols_to_drop)

        return new_df
    else:
        return df

答案 3 :(得分:0)

这样做的间接方式之一是

import pyspark.sql.functions as func

for col in sdf.columns:
if (sdf.filter(func.isnan(func.col(col)) == True).count() == sdf.select(func.col(col)).count()):
    sdf = sdf.drop(col) 

<强>更新
上面的代码删除所有nan的列。如果您正在寻找所有空值,那么

import pyspark.sql.functions as func

for col in sdf.columns:
if (sdf.filter(func.col(col).isNull()).count() == sdf.select(func.col(col)).count()):
    sdf = sdf.drop(col)

如果我找到一些最佳方式,我会更新我的答案: - )

答案 4 :(得分:0)

或者只是

max(values)  # -50

答案 5 :(得分:0)

对我来说,它的工作方式不同于@Suresh答案:

nonNull_cols = [c for c in original_df.columns if original_df.filter(func.col(c).isNotNull()).count() > 0]
new_df = original_df.select(*nonNull_cols)

答案 6 :(得分:0)

这是一个健壮的解决方案,它考虑了列中可能存在的所有null组合。首先,找到所有空列,然后将其删除。它看起来很长而且很麻烦,但是实际上这是一个可靠的解决方案。仅一个循环用于查找null列,并且不应用内存密集型函数(例如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 null_columns:
    df = df.drop(column_)
    return df

df = drop_column(null_columns, df)
df.show()

输出: enter image description here

答案 7 :(得分:0)

只需从上面的答案中整理出来,就为我的用例编写了自己的解决方案。

我实质上想做的是从pyspark数据框中删除所有具有100%空值的列。

MethodNotAllowedHttpException

答案 8 :(得分:0)

创建一个数据框:

df = spark.createDataFrame(
    [
        (1, 'baz'),
        (2, 'baz')
    ],
    ['foo','bar']
)

添加空列:

df = df.withColumn('foobar', lit(None))

制作非空列的列表:

non_null_columns = df.summary('count').drop('summary').columns

创建 df 中也存在于 non_null_columns 中的列的列表理解,并使用这些列从您的 df 中进行选择:

df.select([col for col in df.columns if col in non_null_columns]).show()

打印:

+---+---+
|foo|bar|
+---+---+
|  1|baz|
|  2|baz|
+---+---+