使用Pyspark,如何选择/保留包含非空值的DataFrame的所有列;或者等效地删除所有不包含数据的列。
编辑:根据Suresh请求,
for column in media.columns:
if media.select(media[column]).distinct().count() == 1:
media = media.drop(media[column])
这里我假设如果count是1,那么它应该是Nan。但我想检查一下是否是楠。如果还有其他内置火花功能,请告诉我。
答案 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()
答案 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|
+---+---+