Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 在大型矩阵中执行单元计算的有效方法_R_Binary_Sapply - Fatal编程技术网

R 在大型矩阵中执行单元计算的有效方法

R 在大型矩阵中执行单元计算的有效方法,r,binary,sapply,R,Binary,Sapply,我试图从NASA的云掩模中间产品中获得2位8位值 矩阵的维数为3200 x 3248。我必须对数千个数据集进行转换 下面是我要进行此转换的数据集之一 这是我的密码: library(binaryLogic) test = as.logical(c(0,0)) #n_row <- nrow(cmask_1) n_row <- 100 cmask_2bits <- matrix(nrow=n_row, ncol=ncol(cmask_1)) t1 <- Sys.time(

我试图从NASA的云掩模中间产品中获得2位8位值

矩阵的维数为3200 x 3248。我必须对数千个数据集进行转换

下面是我要进行此转换的数据集之一

这是我的密码:

library(binaryLogic)
test = as.logical(c(0,0))
#n_row <- nrow(cmask_1)
n_row <- 100
cmask_2bits  <- matrix(nrow=n_row, ncol=ncol(cmask_1))

t1 <- Sys.time()

for(i in 1:n_row){
  cmask_2bits[i,] <- sapply(cmask_1[i,], function (x) ifelse(identical(as.logical(as.binary(x, n=8)[5:6]), test), 0, 1))
}

t2 <- Sys.time()

time <- difftime(t2, t1)


t1_mthd2 <- Sys.time()

cmask_2bits_mthd2  <- matrix(nrow=n_row, ncol=ncol(cmask_1))

cmask_2bits_mthd2 <- mapply(function (x) 
ifelse(identical(as.logical(as.binary(x, n=8)[5:6]), test), 0, 1), cmask_1[1:n_row,])

cmask_2bits_mthd2 <- matrix(cmask_2bits_mthd2, nrow=n_row, ncol=ncol(cmask_1))

t2_mthd2 <- Sys.time()

time_mthd2 <- difftime(t2_mthd2, t1_mthd2)

time_mthd2 - time
库(二进制逻辑)
测试=逻辑(c(0,0))

#n_row对于更广泛的问题,当每个单元的操作相同时,对大型矩阵进行单元操作的最有效方法是使用内置的矢量化操作。R中的矩阵实际上只是一个向量,包含一些关于维度的元数据。对于您的特定问题,除了矢量化之外,它看起来像是
binaryLogic.asBinary
在计算上没有效率。对于8位整数中位5和6为零的简单情况,只需使用整数数学即可:

(((cmask_1 %% 128) %% 64) < 16) + 0

感谢@W.Murphy给出了这个简单明了的答案。整数除法后的正确答案应为

(((((()((((cmask_1%%256%%128)%%64%%32%%16)和((((cmask_1%%256%%128)%%64%%32%%16))+0

我想把余数限制在3到16之间,这样在这个间隔内的数字将被8或4除,或者两者都除


再次感谢

我认为最快的方法是使用位逻辑运算符。如果要从整数X中提取位3和4,可以使用“X和12”(4+8=12)。因此,如果设置了第3位,则得到“4”;如果设置了第3位和第4位,则得到“8”;如果设置了第3位和第4位,则得到“12”

在R中有一个包“bitops”,它支持您需要的操作:

library(bitops)
mat_cmask = as.matrix(df_cmask)
v = as.vector(mat_cmask, mode="integer")
v1 = bitAnd(v, 12) # there are still values 4, 8 and 12
v2 = as.integer(v1>0)
result = matrix(v2, nrow=nrow(cmask), ncol(cmask)) 
result[1:10, 1:10]

最好的,Stefan

测试的值是多少?
作为.binary的包是什么please@W.Murphy编辑!不确定这是不是正确的,所以我建议你把它作为一个评论,以防你想探究它。您的代码使用
sapply()
。当前答案中的矢量化数学可能是最好的方法,但为了以防万一,我会尝试重新编写代码,并在子集3种方式上测试性能-两种方式加上使用
map()
的版本。如果你能以这种方式重写它,你可能会看到意想不到的提升。在不同的用例中,不同的方法比其他方法工作得更快
map()
需要在矩阵上映射一个函数,如果可以的话。谢谢你的代码。它给出的结果非常快。但我刚刚编辑了我的问题,即前10 x 10矩阵观测值应与图像中的相同。我还检查了HDFView软件中的这些位,确认这些转换是正确的。但是代码给了我不同的建议。你的建议很简单,但需要修正。我编辑了一个问题,我感兴趣的2位是第3位和第4位,即2^3和2^2的值。在这种情况下,我可以按照您的代码写下(((((3%%256)%%128)%%64)%%32)%%16)%%8)%%4)>2)+0但是,不清楚cmask_1中的数字是否除以8和4。例如,15和3在4除后都有3的余数。但是3不被8和4除,而15被8和4除。在这种情况下,3应该重新编码为0,而15是1。@Mustafa感谢您的澄清;我想知道我是不是把钻头的顺序倒过来了。也许可以简化您添加的答案,但有一件事我仍然不确定:这两个位中的哪些值应该输出为零对一?此数据产品的文档说明,我感兴趣的2位代表云掩码的值:自信清晰、清晰、多云和自信多云。因为2位表示00、01、10和11的值,如果我没有错的话。然后,我的目标是获得“自信清晰”元素的云掩码,这样我想从我感兴趣的2位中得到00。这是文档的链接(第10页)。
library(bitops)
mat_cmask = as.matrix(df_cmask)
v = as.vector(mat_cmask, mode="integer")
v1 = bitAnd(v, 12) # there are still values 4, 8 and 12
v2 = as.integer(v1>0)
result = matrix(v2, nrow=nrow(cmask), ncol(cmask)) 
result[1:10, 1:10]