我正在通过从各种网站上抓取数据来构建一个数据集,用于股票信号预测算法。我的算法的设置方式包括对循环进行分层,并加载数千个URL,因为每个链接都指向股票及其各种定量统计数据。需要帮助提高处理速度。有什么建议吗?
我已经和一些不同的人讨论过如何解决这个问题,有些人建议进行矢量化,但这对我来说是新的。我也尝试过切换到数据表,但没有看到太大的变化。eval行是我学会的一个技巧,可以按照我想要的方式处理数据,但我认为这可能是它速度慢的原因,但我对此表示怀疑。我也对远程处理感到好奇,但这可能超出了R世界。
对于下面的代码,想象一下,对于我想要加载的来自不同网站的其他变量,还有4个类似的部分,所有这些块都在一个更大的For循环中,因为我正在生成两个数据集(set=c("训练,测试"))。
tryCatch用于防止在加载URL时遇到错误时停止代码。url被加载到一个列表中,每个股票一个,所以它们很长。第二个for循环从URLS中抓取数据,并将其正确格式化后发布到数据帧中。
library(quantmod)
library(readr)
library(rvest)
library(data.table)
urlsmacd <- vector("list", length =
eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep = "")))))
for(h in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep =
""))))){
urlsmacd[h] <- paste0('http://www.stockta.com/cgi-bin/analysis.pl?
symb=',eval(parse(text=as.name(paste0(set[y],"[,1][h]", sep =
"")))),'&mode=table&table=macd&num1=1', sep = '')
}
for(j in 1:eval(parse(text=as.name(paste0("nrow(", set[y], ")", sep =
""))))){
tryCatch({
html <- read_html(urlsmacd[[j]])
#get macd html
MACD26 <- html_nodes(html,'.borderTd~ .borderTd+ .borderTd:nth-child(3)
font')
MACD26 <- toString(MACD26)
MACD26 <- gsub("<[^>]+>", "", MACD26)
if(!is.na(MACD26)){
MACD26 <- as.double(MACD26)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD26[j] <- MACD26"))))
MACD12 <- html_nodes(html,'.borderTd+ .borderTd:nth-child(2) font')
MACD12 <- toString(MACD12)
MACD12 <- gsub("<[^>]+>", "",MACD12)
if(!is.na(MACD12)){
MACD12 <- as.double(MACD12)
}
eval(parse(text=as.name(paste0(set[y],"$","MACD12[j] <- MACD12"))))
}, error=function(e){cat("ERROR :",conditionMessage(e), "n")})
}
所有这些都说了算,这个过程大约需要6个小时。按照这个速度,减少这个过程的时间会让我的项目进展得更容易。
感谢StackOverflow的支持。
检查doParallel包。它有一个foreach循环的并行实现。它允许您使用更多的CPU核心(如果有可用的话)来为定义的函数执行并行R会话。例如:
library(doParallel)
no_cores <- detectCores() - 1
cl <- makeCluster(no_cores, type="FORK")
registerDoParallel(cl)
result <- foreach(i=10:10000) %dopar%
getPrimeNumbers(i)
如果url存储在一个列表中,那么还有一个并行的lapply。
这个例子取自这个伟大的帖子:
https://www.r-bloggers.com/lets-be-faster-and-more-parallel-in-r-with-doparallel-package/amp/
希望能有所帮助。