当前位置: 首页 > 知识库问答 >
问题:

如何在R中高效地找到阈值以上的最长值序列

伯庆
2023-03-14

我正在进行温度的时空观测,存储在大小为100*100*504(100*100网格,代表21天的504个不同小时)的阵列中。我正在根据这些观察结果计算不同时期(3到21天)的各种指标,这显然需要一些时间,我正在考虑提高计算效率。我不太习惯R,所以我不确定我所做的是不是最有效的方法。

我想做的事情之一是找到(每个细胞)温度高于某个阈值的最长连续时间。这就是我此刻正在做的事情:

    < li >首先,我使用以下函数根据阈值计算一个布尔数组。
utci_test = array(runif(100*100*504, min = 18, max = 42), c(100,100,504))
to_hs = function(utci, period=1:length(utci[1,1,]), hs_threshold){
  utci_hs = utci*0
  utci_hs[which(utci > hs_threshold)] = 1
  utci_hs[is.na(utci)] = 0
  return(utci_hs)
}
max_duration_hs = function(utci_hs, period=1:length(utci_hs[1,1,]) ){
  apply(utci_hs, MARGIN=c(1,2), FUN=function(x){
    r = rle(x)
    max(r$lengths[as.logical(r$values)], fill = 0)
  })
}

考虑到所需的时间,我注意到第二步需要一些时间(请记住,我必须重复此操作总共8000次)

system.time(to_hs(utci_test, hs_threshold=32.0))
# utilisateur     système      écoulé 
#      0.051       0.004       0.055 
system.time(to_hs(utci_test, hs_threshold=32.0))
# utilisateur     système      écoulé 
#      0.053       0.000       0.052 
utci_test_sh = to_hs(utci_test, hs_threshold=32.0)
system.time(max_duration_hs(utci_test_sh))
# utilisateur     système      écoulé 
#      0.456       0.012       0.468 

所以,我想知道是否有一种更有效的方法来实现这一点,因为我认为转换为rle对象可能效率低下?

共有1个答案

蒙经纶
2023-03-14

你可以通过编写你自己版本的rle()函数来获得一点减速带,因为你知道你想要运行1,并且做的比较少一点。这让你快了大约2倍,在我的机器(通用macbook)上下降到大约250毫秒左右的中值时间。

如果你必须这样做 8,000 次,你将通过并行化代码以在多核机器上运行来节省自己的大部分时间,这在 R 中很简单(例如查看并行包)。

在加速的代码下方。

# generate data
set.seed(123)
utci_test <- array(runif(100*100*504, min = 18, max = 42), c(100,100,504))

# original functions
to_hs = function(utci, period=1:length(utci[1,1,]), hs_threshold){
  utci_hs = utci*0
  utci_hs[which(utci > hs_threshold)] = 1
  utci_hs[is.na(utci)] = 0
  return(utci_hs)
}

max_duration_hs = function(utci_hs, period=1:length(utci_hs[1,1,]) ){
  apply(utci_hs, MARGIN=c(1,2), FUN=function(x){
    r = rle(x)
    max(r$lengths[as.logical(r$values)], fill = 0)
  })
}

# helper func for rle
rle_max <- function(v) {
  max(diff(c(0L, which(v==0), length(v)+1))) - 1
}

max_dur_hs_2 <- function(utci_hs) {
  apply(utci_hs, MARGIN=c(1,2), FUN= rle_max)
 }

# Check equivalence
utci_hs <- to_hs(utci = utci_test, hs_threshold = 32)

all.equal(max_dur_hs_2(utci_hs), 
          max_duration_hs(utci_hs))
#> [1] TRUE

# Test speed
library(microbenchmark)

microbenchmark(max_dur_hs_2(utci_hs), 
               max_duration_hs(utci_hs))
#> Unit: milliseconds
#>                      expr      min       lq     mean   median       uq      max
#>     max_dur_hs_2(utci_hs) 216.1481 236.7825 250.9277 247.9918 262.4369 296.0146
#>  max_duration_hs(utci_hs) 454.5740 476.5710 501.5119 489.9536 509.8750 774.9963
#>  neval cld
#>    100  a 
#>    100   b

创建于 2020-05-07 由 reprex 软件包 (v0.3.0)

 类似资料:
  • 我需要帮助确定R中观察组中最长的连续值序列(=1)。 我有城镇月降雨量的数据。我需要确定每年月降雨量高于年平均值的最长时期(rain_above = 1)。如果每年有两个等长的时期,我想确定总降雨量最大的时期。 一些示例数据: 在df,A镇在2000年的第4个月到第8个月之间有一个雨季。这是rain_above=1的唯一时期。 B镇在2001年有一个雨季,在第1个月和第3个月之间。尽管有两个长度相

  • 本文向大家介绍如何找到R中向量的最小值和最大值的索引?,包括了如何找到R中向量的最小值和最大值的索引?的使用技巧和注意事项,需要的朋友参考一下 在分析项目中进行数据探索时,有时我们需要找到一些值的索引,主要是最小值和最大值的索引,以检查相应的数据行是否包含一些关键信息,或者我们可能会忽略它。此外,如果我们不想忽略它们,有时会根据数据特征将这些值转换为另一个值。 示例

  • 我有数据,我想应用滚动函数来检测哪个点的值大于特定阈值。 我想要的是找到下一个2个值高于某个阈值(例如30)的行。这将产生以下结果: 我有一个大的数据集(几百万行),所以我试图找到一个有效的解决方案。也许使用?由reprex包(v0.2.1)在2019-02-26创建

  • 本文向大家介绍如何找到R数据帧中所有值的均值?,包括了如何找到R数据帧中所有值的均值?的使用技巧和注意事项,需要的朋友参考一下 如果数据框具有所有数字列,那么我们可能有兴趣查找该数据框中所有值的均值,但是由于数据框对象不是数字,因此无法直接完成此操作。因此,要查找R数据帧中所有值的均值,我们需要先将其转换为矩阵,然后使用均值函数。 示例 请看以下数据帧- 输出结果 使用均值函数查找均值- 示例 输

  • 请告诉我如何在数据帧中查找列的值 在@Dadep的答案中,链接给出了正确的答案

  • 我有一个非常大(约10万)的字典列表: 给定一个ID(例如),我如何以有效的方式找到相应的?我必须为每个列表多次这样做(我有几个这样的大列表,每个列表我有几个令牌ID)。 我目前正在遍历列表中的每个词典,检查是否与我的输入ID匹配,如果匹配,我将获得