У меня очень мало опыта работы с pyspark, но, возможно, неплохо было бы создать фрейм данных с счетчиками и преобразовать его в pandas
, поскольку у фрейма count будет одна строка:
Начиная с фрейм данных, который выглядит как показано ниже и сохраняется как null_df
+---+---+---+----+
| A| B| C| D|
+---+---+---+----+
| 1| a| b|null|
| 2| c| d|null|
| 3| e| f|null|
+---+---+---+----+
import pyspark.sql.functions as F
counts = null_df.select([F.count(i).alias(i) for i in null_df.columns]).toPandas()
output = null_df.select(*counts.columns[counts.ne(0).iloc[0]])
Или даже преобразование всей первой строки в словарь, а затем l oop по словарю
counts1 = null_df.select([F.count(i).alias(i) for i in null_df.columns])
output2 = null_df.select([k for k,v in counts1.first().asDict().items() if v >0])
, что дает следующее:
+---+---+---+
| A| B| C|
+---+---+---+
| 1| a| b|
| 2| c| d|
| 3| e| f|
+---+---+---+
тесты, как проверено в моей системе:
%%timeit
counts = null_df.select([F.count(i).alias(i) for i in null_df.columns]).toPandas()
output = null_df.select(*counts.columns[counts.ne(0).iloc[0]])
#8.73 s ± 412 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
counts1 = null_df.select([F.count(i).alias(i) for i in null_df.columns])
output2 = null_df.select([k for k,v in counts1.first().asDict().items() if v >0])
#9.43 s ± 253 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
counts1 = null_df.select([F.count(i).alias(i) for i in null_df.columns])
output1 = null_df.select([c for c in counts1.columns if counts1[[c]].first()[c] > 0])
#35.3 s ± 1 s per loop (mean ± std. dev. of 7 runs, 1 loop each)