如何根据列数据类型在sparklyr中最佳地子集化Spark数据框

我正在将许多列转换为虚拟变量。我想从数据框中删除原始的分类变量。我在sparklyr中苦于找出如何操作。在dplyr中这是很直接的,但dplyr的功能在sparklyr中不起作用。

例如:

首先创建一个Spark数据框:

    ###创建虚拟数据以了解模型矩阵公式在sparklyrv1 <- sample( LETTERS[1:4], 50000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.05))v2 <- sample( LETTERS[5:6], 50000, replace=TRUE, prob=c(0.7,0.3))v3 <- sample( LETTERS[7:10], 50000, replace=TRUE, prob=c(0.3, 0.2, 0.4, 0.1))v4 <- sample( LETTERS[11:15], 50000, replace=TRUE, prob=c(0.1, 0.1, 0.3, 0.05,.45))v5 <- sample( LETTERS[16:17], 50000, replace=TRUE, prob=c(0.4,0.6))v6 <- sample( LETTERS[18:21], 50000, replace=TRUE, prob=c(0.1, 0.1, 0.65, 0.15))v7 <- sample( LETTERS[22:26], 50000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.03,.02))v8 <- rnorm(n=50000,mean=.5,sd=.1)v9 <- rnorm(n=50000,mean=5,sd=3)v10 <- rnorm(n=50000,mean=3,sd=.5)response <- rnorm(n=50000,mean=10,sd=2)dat <- data.frame(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,response)write.csv(dat,file='fake_dat.csv',row.names = FALSE)#push "fake_dat" to the hdfslibrary(dplyr)library(sparklyr)#configure the spark session and connectconfig <- spark_config()config$`sparklyr.shell.driver-memory` <- "2G" #change depending on the size of the dataconfig$`sparklyr.shell.executor-memory` <- "2G"# sc <-  spark_connect(master='local', spark_home='/usr/hdp/2.5.0.0-1245/spark',config = config)# scsc <-  spark_connect(master='yarn-client', spark_home='/usr/hdp/2.5.0.0-1245/spark',config = config)sc#can also set spark_home as '/usr/hdp/current/spark-client'#read in the data from the hdfsdf <- spark_read_csv(sc,name='fdat',path='hdfs://pnhadoop/user/stc004/fake_dat.csv')#create spark tabledat <- tbl(sc,'fdat')

现在创建虚拟变量:

for(i in 1:7){  dat <- ml_create_dummy_variables(x=dat,colnames(dat)[i], reference = NULL)}

我可以简单地使用以下方法删除原始的分类变量:

drop.cols <- colnames(dat)[1:7]dat1 <-  dat %>%  select(-one_of(drop.cols))

然而,我实际处理的数据有300个分类变量。我需要一种快速的方法来识别哪些列是字符/因子类型。在将这些列转换为虚拟变量后,我可以删除原始的分类变量。我尝试了以下方法:

test <-  dat %>%  select_if(is.character)

然后我得到了以下错误:

Error: Selection with predicate currently require local sources

我也尝试了:

cls <- sapply(dat, class)cls

但我得到的是:

> cls         src         ops    [1,] "src_spark" "op_base_remote"    [2,] "src_sql"   "op_base"    [3,] "src"       "op"

有什么想法吗?


回答:

称之为“最佳”可能有些夸张,但你可以尝试以下方法(使用purr是为了方便):

columns_for_type <- function(sc, name, type="StringType") {  spark_session(sc) %>%     invoke("table", name) %>%     # Get (name, type) tuples    invoke("dtypes") %>%    # Filter by type    purrr::keep(function(x) invoke(x, "_2") == type) %>%     purrr::map(function(x) invoke(x, "_1"))}

可以按以下方式使用:

library(sparklyr)library(dplyr)sc <- spark_connect(master = "local[*]")iris_tbl <- copy_to(sc, iris, name="iris", overwrite=TRUE)columns_for_type(sc, "iris", "StringType")
[[1]][1] "Species"
columns_for_type(sc, "iris", "DoubleType")
[[1]][1] "Sepal_Length"[[2]][1] "Sepal_Width"[[3]][1] "Petal_Length"[[4]][1] "Petal_Width"

结果可以传递给select_

iris_tbl %>% select_(.dots=columns_for_type(sc, "iris", "StringType"))
Source:   query [150 x 1]Database: spark connection master=local[8] app=sparklyr local=TRUE   Species     <chr>1   setosa2   setosa3   setosa4   setosa5   setosa6   setosa7   setosa8   setosa9   setosa10  setosa# ... with 140 more rows

你可以通过取一行作为data.frame来使用类似的方法:

iris_tbl %>% head(n=1) %>% as.data.frame %>% lapply(class)

但这需要额外的Spark操作。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注