如何在PySpark DataFrame中删除所有空值列?

11
我有一个大型数据集,我想删除包含null值的列,并返回一个新的数据框。我该如何做到这一点?下面的代码只能删除一个包含null值的列或行。
df.where(col("dt_mvmt").isNull()) #doesnt work because I do not have all the columns names or for 1000's of columns
df.filter(df.dt_mvmt.isNotNull()) #same reason as above
df.na.drop() #drops rows that contain null, instead of columns that contain null
例如
a |  b  | c
1 |     | 0
2 |  2  | 3

在上述情况下,它将删除整个列B,因为它的一个值为空。


1
请尝试检查 - http://spark.apache.org/docs/2.1.0/api/python/pyspark.sql.html#pyspark.sql.DataFrameNaFunctions - Tom Ron
2个回答

16
这里提供一种可能的方法来删除所有包含空值的列:请参见此处获取有关计算每列空值数量代码的来源。
import pyspark.sql.functions as F

# Sample data
df = pd.DataFrame({'x1': ['a', '1', '2'],
                   'x2': ['b', None, '2'],
                   'x3': ['c', '0', '3'] })
df = sqlContext.createDataFrame(df)
df.show()

def drop_null_columns(df):
    """
    This function drops all columns which contain null values.
    :param df: A PySpark DataFrame
    """
    null_counts = df.select([F.count(F.when(F.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 > 0]
    df = df.drop(*to_drop)
    return df

# Drops column b2, because it contains null values
drop_null_columns(df).show()

在此之前:

+---+----+---+
| x1|  x2| x3|
+---+----+---+
|  a|   b|  c|
|  1|null|  0|
|  2|   2|  3|
+---+----+---+

之后:

+---+---+
| x1| x3|
+---+---+
|  a|  c|
|  1|  0|
|  2|  3|
+---+---+

希望这可以帮助你!

是的先生!它确实有帮助。太棒了!另外的三行代码也完美地解决了问题。 - PolarBear10
1
很高兴我能帮到你!我移除了阈值部分,也许对那些偶然发现这个问题的人来说有点混淆。 - Florian
@Florian 你应该保留阈值部分,这样它就成为了一个完整的答案!这将非常有帮助,谢谢 :) - pissall

1
如果我们需要保留至少有一个已检查列不为空的行,则使用此方法。执行时间非常短。
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)))```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接