【问题标题】:faster way to use apply in large array (maybe involving parallelization)?在大型数组中使用应用程序的更快方法(可能涉及并行化)?
【发布时间】:2019-04-13 09:20:15
【问题描述】:

我在 R 中有一个大数组,比方说,

A = array(rnorm(100*100*30*30*100),dim=c(100,100,30,30,100))

我想找到第 4 维中小于 1 的第一个条目:

first_entry = apply(A,c(1,2,3,5),function(x) min(which(x < 1)))

由于阵列太大,这需要一段时间,在我的计算机上大约需要 20 秒,而且我将在未来对很多阵列执行此操作。 for 循环的速度大致相同。我也尝试过使用 parApply,但它需要大约相同的时间,如果不是更长的话。可能我的功能不够“复杂”,无法通过并行化来实现速度增益。有没有更快的方法来做到这一点?实际上,理想情况下,我希望能够将另一个数组 B(与 A 具有相同的维度)中的值设置为 0。所以,类似于,

B[first_entry] = 0

请注意,鉴于“apply”(上图)的当前输出,这不起作用,因为 first_entry 的尺寸是 100x100x30x100。

【问题讨论】:

  • 最好显示一个小数据用于测试目的。除了min,您可以使用索引作为子集的第一个元素,即which(x &lt; 1)[1]。另外,通过查看代码,您需要小于 1 的最小值还是小于 1 的第一个索引?
  • @akrun 哦,是的,呃,这有帮助。 :) 我需要第一个索引,但正如我所提到的,如果我能以一种可以调用另一个数组 B 中的相应值的方式输出结果,那将是很好的,它的大小与 A 相同。跨度>

标签: arrays r apply doparallel


【解决方案1】:

我稍微简化了您的示例(我的机器可能比您的慢!),并添加了一些时间测量。当我使用 parApplym 而不是 applym 时,代码会快一点(parApply 为 2.4 秒,而 apply 为 3.8 秒)。

如果 parApply 确实在您的机器上产生了类似的结果,您是否考虑改为以多线程方式运行更广泛的任务?您提到您将为很多数组执行此操作。因此,与其使查找过程更快,您可以同时运行多个查找吗?

# Create data
A = array(rnorm(100*100*30),dim=c(100,100,30))

# Using apply
start.time <- Sys.time()
first_entry = apply(A,c(1,2,3),function(x) min(which(x < 1)))
print(Sys.time() - start.time)

# Load packages
library(parallel)

# Create cluster and export
nrCores <- detectCores()
cl <- makeCluster(nrCores)
clusterExport(cl=cl, varlist=c("A"))

# Using parApply
start.time <- Sys.time()
first_entry = parApply(cl=cl,A,c(1,2,3),function(x) min(which(x < 1)))
print(Sys.time() - start.time)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2021-05-26
    相关资源
    最近更新 更多