更有效的迭代方法计算列

时间:2017-09-23 18:36:10

标签: apache-spark pyspark

我有一个非常宽的数据框> 10,000列,我需要计算每个列中的空值百分比。现在我正在做:

threshold=0.9
for c in df_a.columns[:]:
    if df_a[df_a[c].isNull()].count() >= (df_a.count()*threshold):
        # print(c)
        df_a=df_a.drop(c)

当然这是一个缓慢的过程,有时会崩溃。我缺少一种更有效的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

根据数据框的大小,您可以采取的策略很少。代码对我来说很好。您需要遍历每一列并计算空值的数量。

一种策略是缓存输入数据帧。这将实现更快的过滤。但是,如果数据帧不是很大,则可以使用它

另外

df_a=df_a.drop(c) 

我对此持怀疑态度,因为这会改变循环中的数据帧。最好保留空列名称,然后在单独的循环中从数据帧中删除。

如果数据帧很大并且您无法完全缓存它,则可以将数据帧划分为一些有限的可管理列。就像每个采用100列并缓存较小的数据帧并在循环中运行分析100次。

现在,在这种情况下,您可能希望跟踪已分析的列列表与尚待分析的列分开。这样,即使作业失败,您也可以从其余列开始分析。

答案 1 :(得分:0)

使用pyspark时应该避免迭代,因为它不再分发计算。 在列上使用count将计算非{null}元素的count

threshold = 0.9
import pyspark.sql.functions as psf
count_df = df_a\
    .agg(*[psf.count("*").alias("count")]+ [psf.count(c).alias(c) for c in df_a.columns])\
    .toPandas().transpose()

第一个元素是数据框中的行数:

total_count = count_df.iloc[0, 0]
kept_cols = count_df[count_df[0] > (1 - threshold)*total_count].iloc[1:,:]
df_a.select(list(kept_cols.index))