使用SparkR删除仅包含NA值的列

ubby3x7f  于 2022-10-07  发布在  Spark
关注(0)|答案(1)|浏览(109)

我正在使用Databricks中的SparkR来操作大型 Dataframe 。我有一个spark DataFrame df,我想从其中删除仅包含NA值的所有列。在典型的R中,我会使用一种整齐的方法

df %>% select_if(~any(!is.na(.)))

或以R为底数

df[!sapply(df, function(x) all(is.na(x)))]

然而,这两种方法似乎都不适用于SparkR。我还想尽可能多地使用Spark的能力来分发工作。我找到了以下解决方案

nacols<- sapply(columns(df), function(c){
  nbna <- SparkR::select(df, c) %>% SparkR::na.omit() %>% SparkR::nrow()
  return(nbna != 0)
})

df_nona<- df %>% SparkR::select(columns(df)[c(T, nacols)])

但我认为,考虑到SparkR没有分发sapply的工作,它的效率很低。

如果你能想出更好的办法,请告诉我。我也愿意用python语言来完成这部分脚本,也可以使用pysppark。但是,由于我使用的是高并发集群,所以不能使用Scala代码。

非常提前感谢您。

mklgxw1f

mklgxw1f1#

我已经能够使用以下代码删除仅包含NAS的列:

library(SparkR)

df <- data.frame(V1 = base::sample(1 : 10,5),
                 V2 = base::rep(NA,5), 
                 V3 = base::sample(1 : 10,5),
                 V4 = base::rep(NA,5), 
                 V5 = base::rep(NA,5), 
                 X = runif(n = 5, min = 0, max = 5))

sdf <- createDataFrame(df)
col_Names <- colnames(sdf)
nb_Col_Names <- length(col_Names)
vec_Bool <- rep(FALSE, nb_Col_Names)

for(i in 1 : nb_Col_Names)
{ 
  dim_Temp <- dim(dropna(select(sdf, col = col_Names[i]), how = "all"))
  if(dim_Temp[1] != 0) vec_Bool[i] <- TRUE
}

col <- col_Names[vec_Bool]
newdf <- select(sdf, col = col)
as.data.frame(newdf)

V1 V3        X
1  6  1 2.286716
2 10  3 3.532843
3  2  9 2.030851
4  8  6 3.304420
5  4 10 1.596272

相关问题