【问题标题】:filtering 3D array using data in similar array使用相似数组中的数据过滤 3D 数组
【发布时间】:2016-07-26 01:21:40
【问题描述】:

我有两个 3-D 数组,其中一个包含数据,另一个包含元数据。元数据是日期签名,因此可以使用以下内容生成示例:

datamatrix <- array(data = c(rep(0,9), rep(0,9),(sample(0:100, 9)/1000), (sample(30:50, 9)/100), (sample(70:80,9)/100), (sample(30:50,9)/100), rep(0,9), rep(0,9)), dim = c(3,3,8))
timematrix <- array(data = c(sample(1:20), sample(30:50, 9), sample(70:90, 9), sample(110:130,9), sample(150:170,9), sample(190:210,9), sample(230:250,9), sample(260:280,9)), dim = c(3,3,8))

我希望构造一个新的 3D 数组,其中填充来自第一个矩阵 (datamatrix) 和一堆 NA 的数据,以便 datamatrix 中的元素 i 落入其对应的日期(源自timematrix 中的相应元数据)在最终的workingdata 3D 数组中,如下所示:

workingdata <- array(data = NA,
                 dim = c(3,3,365))

for (i in 1:length(datamatrix)){
  location <- i
  locationguide <- location%%9
  locationfinal <- locationguide%%3
  if (locationfinal == 0){
    a <- 3
    b <- 3
  }
  if (locationfinal == 1){
    a <- 1
    b <- 1
  }  
  if (locationfinal == 2){
    a <- 1
    b <- 2
  }
  if (locationfinal == 3){
    a <- 1
    b <- 3
  }
  if (locationfinal == 4){
    a <- 2
    b <- 1
  }
  if (locationfinal == 5){
    a <- 2
    b <- 2
  }
  if (locationfinal == 6){
        a <- 2
        b <- 3
      }
  if (locationfinal == 7){
    a <- 3
    b <- 1
  }
  if (locationfinal == 8){
    a <- 3
    b <- 2
  }
  value <- datamatrix[i]
  day <- timematrix[i]
  workingdata[a,b,day] <- datamatrix[i]
}

我正在使用的数据集有数千列宽且排长相当。当前的方法可以完成这项工作,但是在实际数据中使用for 循环将永远需要,并且由于所有if 的要求而对其进行编码将是荒谬的。有谁知道过滤此类数据的更好方法?

对于我想要的对观众友好的概念,ESRI 的图片最好地总结了它: http://pro.arcgis.com/en/pro-app/tool-reference/space-time-pattern-mining/GUID-42A31756-6518-41E9-A900-2C892AF4023A-web.png

我正在为时间的 z 维度拍摄,每天一个街区,其中观察结果落在 z 轴上的相应行中,但在 x 和 y 维度上保持在其原始位置。

【问题讨论】:

  • 那么datamatrixtimematrix 是数组吗?
  • 我不太确定你的if 语句系列中的启发式。也许你可以详细说明?
  • 为什么timematrix中有0s? workingdata 是否从第 0 天的第 1 行开始?
  • 是我还是第三个之后的所有if 都是多余的,因为locationfinal 永远不会大于2?
  • 详细说明:不,时间上不应该有任何 0。我已经更新了这段代码。 datamatrixtimematrix 都是 3D 数组。 if 语句都是必需的,因为在我原来的 for 循环中,3D 数组是在一个大字符串中读取的(因为它是 1:length(),所以由于 3x3 维度,余数 9 为您提供了最终位置的索引workingdata中的数据点。

标签: arrays r optimization


【解决方案1】:

我不确定您的 for 循环到底在做什么,它可能无法完全完成您想要做的事情。没有把握。比如查看((1:30)%%9)%%3的结果。

但是,根据您对问题的描述,您可能想要执行以下操作:

workingdata <- array(data = NA, dim = c(3,3,365))
for (i in 1:dim(datamatrix)[1]) {
  for (j in 1:dim(datamatrix)[1]) {
    workingdata[i, j, timematrix[i, j, ]] <- datamatrix[i, j, ]
  }
}

请注意,当您的 timematrix 中有日期为 0 时(如在您的示例数据中),这将不起作用,因为 R 具有基于 1 的索引。

【讨论】:

  • 谢谢!这是一种比我的示例更优雅的方法。这导致了我的问题的症结所在:没有for 循环我怎么能做到这一点?它们显然效率低下,而我的实际数据集非常庞大......
  • R 中的数组对于高效的工具来说有点麻烦(data.frames 这样更好),但你可以看看?plyr::aaply
【解决方案2】:

最终答案:Axeman 的解决方案通过以下方法在 3 个维度上起作用:

workingdata <- array(data = NA, dim = c(3,3,365))

for (i in 1:dim(datamatrix)[1]) {
  for (j in 1:dim(datamatrix)[2]) {
    for(k in 1:dim(datamatrix)[3]){
      workingdata[i, j, timematrix[i, j, k]] <- datamatrix[i, j, k]
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    • 2023-04-06
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 2013-06-18
    相关资源
    最近更新 更多