Apache spark 如何删除pyspark中的常量列,而不是包含null和其他值的列?
一个类似的问题被问了好几次,并得到了回答。例如: 但是,我发现,没有一个答案能解决这个问题,Apache spark 如何删除pyspark中的常量列,而不是包含null和其他值的列?,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,一个类似的问题被问了好几次,并得到了回答。例如: 但是,我发现,没有一个答案能解决这个问题,CuthDistabor()/Case>不把空值视为一个不同的值。因此,只有两个结果null和一个none null值的列也将被删除 一个丑陋的解决方案是将spark数据框中的所有空值替换为数据框中其他地方不存在的值。但就像我说的那样,这真的很难看。您可以在countDistinct中添加一个整数0或1,这取决于列中是否有空值: # example dataframe df.show() +---+---
一个丑陋的解决方案是将spark数据框中的所有空值替换为数据框中其他地方不存在的值。但就像我说的那样,这真的很难看。您可以在
countDistinct
中添加一个整数0或1,这取决于列中是否有空值:
# example dataframe
df.show()
+---+---+----+----+
| a| b| c| d|
+---+---+----+----+
| 1| 1| 1|null|
| 1| 2|null|null|
+---+---+----+----+
import pyspark.sql.functions as F
cnt = df.agg(*[
(F.countDistinct(c) + F.max(F.col(c).isNull()).cast('int')).alias(c)
for c in df.columns
])
cnt.show()
+---+---+---+---+
| a| b| c| d|
+---+---+---+---+
| 1| 2| 2| 1|
+---+---+---+---+
df.drop(*[c for c in cnt.first().asDict() if cnt.first()[c] == 1]).show()
+---+----+
| b| c|
+---+----+
| 1| 1|
| 2|null|
+---+----+
非常感谢。这听起来很合乎逻辑。在我接受你的回答之前,让我很快检查一下。@Mirko有效吗?:)老实说,我不确定。我在数据的一个“小”子集上进行了尝试,但在几个小时后(350万行和100列)都没有完成。今天晚些时候,我将在更小的子集上尝试它。你知道F.max(F.col(c).isNull()).cast('int')是否特别慢吗?我认为
countDistinct
会慢得多,但是没有什么办法可以加快速度。。。它真的需要检查整个数据集。好的,我试了一些方法。首先我有一个问题:cast(“int”)
是否应该在F.max函数中?我改变了这一点,你的代码花了18分钟在一个普通集群上处理7000行和92列。相比之下,df.agg(*(countDistinct(col(c)).alias(c)代表df.columns中的c)).show()花费了不到10秒的时间。这不是很奇怪吗?但我可以确认您的代码实现了它的预期目标:)