使用API​​调用向量化R循环

问题描述

我对向量化的概念还比较陌生,想问一下社区是否对改善我用来下载Bloomberg API数据并将其绑定到矩阵的流程的运行时间有任何建议。

当前,此过程会遍历我的API调用中的每个日期,这需要花费大量时间。我想知道是否可以“矢量化”的方式进行此操作,以便一次进行大量调用,然后绑定到数据帧,从而减少运行时间。 '''

#create fund names to feed through as param in loop below
fundList <- c("fund 1 on bloomberg","fund 2 on bloomberg","fund 3 on bloomberg","fund 4 on bloomberg","fund 5 on bloomberg","fund 6 on bloomberg","fund 7 on bloomberg",)

#create datelist for params for loop
newDateList <- seq(as.Date(today()-1401),length=1401,by="days")
newDateListReformatted <- gsub("-","",newDateList)


#create df object and loop through bloomberg API,assign to dataframe object
df_total = data.frame()

for(fund in 1:length(fundList)){
  
  df_total = data.frame()
  
  for(b in 1:length(newDateListReformatted)){
    ovrd <- c("CUST_TRR_START_DT"=newDateListReformatted[b],"CUST_TRR_END_DT"=newDateListReformatted[b+1])
    print(ovrd)
    model <- bdp(fundList[fund],"CUST_TRR_RETURN_HOLDING_PER",overrides=ovrd)
    print(model)
    df <- data.frame(model)
    df1 <- data.frame(newDateListReformatted[b+1])
    df2 <- cbind(df,df1)
    df_total <- rbind(df_total,df2)
  }
  
  assign(fundList[fund],df_total)

}

'''

首先,循环移动到第一级的某个基金,迭代所有日期,然后一次将行绑定到数据框,然后再移动到fundList中的下一个基金,并再次遍历时间序列。

以这种方式考虑,我将向函数调用多个日期参数的向量,然后“垂直”将它们一次分配给df_total矩阵,且每次分配的数目大于一个,并且每个循环都会增加运行时间。或者,我可以给每个单独的日期打电话,但要用很多资金来完成,然后将它们“水平”分配给矩阵。

任何想法都值得赞赏。

解决方法

向量化包含使我们具有有效实现每个输入的多个参数处理功能的功能。例如,可以使用循环lapply(mtcars,mean)或使用向量化函数colMeans(mtcars)计算列的平均值。后者比使用循环更有效,因为该功能针对输入进行了优化。

在堆栈溢出时,矢量化常常被误认为是代码readability,因此通常使用*apply函数被认为是矢量化,而这些功能对于可读性更有用,并且不能(单独)加速您的代码。

对于您的特定示例,瓶颈(和问题)部分来自对bdp的调用,部分归因于使用cbindrbind和{{1 }}。
为了加速您的代码,我们首先需要知道该函数是如何实现的。从文档中我们可以了解到assignfields接受多个参数。因此,这些参数为securities,而vectorized仅接受覆盖字段的命名向量。这意味着我们可以通过一次性提供所有字段来消除代码中的外部循环。

接下来,为了通过迭代扩展overrides来减少多次调用的开销,我们可以将中间结果存储在data.frame中,然后组合输出。使用此代码,我们可以得到类似于以下代码的内容:

list

请注意,我最后使用n <- length(newDateListReformatted) # Create override matrix (makes it easier to subset,but not strictly necessary periods <- matrix(c(newDateListReformatted[-n],newDateListReformatted[-1]),ncol = 2,byrow = FALSE) colnames(periods) <- c('CUST_TRR_START_DT','CUST_TRR_END_DT') ovrds <- newDateListReformatted models <- vector('list',n - 1) for(i in seq_len(n - 1)){ models[[i]] <- bdp(fundList,'CUST_TRR_RETURN_HOLDING_PER',overrides = periods[i,] ) # Add identifier columns models[[i]][,'CUST_TRR_START_DT'] <- periods[i,1] models[[i]][,'CUST_TRR_END_DT'] <- periods[i,2] } # Combine results in single data.frame (if wanted) model <- do.call(rbind,models) 合并了结果,从而给出了一个do.call(rbind,models),但是可以使用data.frame包或bind_rows中的dplyr也来自rbindlist包。

还请注意,我目前无法访问Bloomberg,也无法测试我的代码是否存在拼写错误。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...