R语言三维数组按指定维度计算元素占比的张量运算实现问题
问题原因
你遇到的non-conformable arrays报错是因为apply(x, c(1,2), sum)返回的是2行2列的二维矩阵,直接和三维的x做除法时,R的默认向量循环规则无法匹配两个对象的维度结构,所以触发报错。
实现方案
方案1:基础R原生sweep函数(无需额外安装包)
sweep是R原生专门用于按指定维度对数组执行批量运算的函数,完美适配你的需求:
# 你的原始数组 x <- array( data = 1:8, dim = c(2, 2, 2), dimnames = list(i = c("i1", "i2"), j = c("j1", "j2"), k = c("k1", "k2")) ) # 计算按前两维求和的基准值 dim_sum <- apply(x, c(1, 2), sum) # 按前两维匹配,执行除法 a <- sweep(x, MARGIN = c(1,2), STATS = dim_sum, FUN = "/")
输出结果和你预期的完全一致:
> a , , k = k1 j i j1 j2 i1 0.1666667 0.3000000 i2 0.2500000 0.3333333 , , k = k2 j i j1 j2 i1 0.8333333 0.7000000 i2 0.7500000 0.6666667
如果你需要分数格式展示,可以加载MASS包的fractions函数:
library(MASS) fractions(a)
就能得到你示例里的分数格式输出。
方案2:手动扩展求和结果维度(更易理解底层逻辑)
你也可以手动把二维的求和结果扩展为和x维度完全一致的三维数组,再直接做除法,R会按元素一一匹配运算:
dim_sum <- apply(x, c(1,2), sum) # 把二维求和矩阵扩展为和x同维度的数组,第三维重复两次求和结果 dim_sum_arr <- array(dim_sum, dim = dim(x), dimnames = dimnames(x)) a <- x / dim_sum_arr
运算结果和方案1完全相同。
方案3:张量计算包实现(适合更高维度/更大规模数据)
如果需要处理更高维度的张量运算,可以用torch或者tensor包的维度广播功能,以torch为例:
library(torch) # 把R数组转为torch张量 x_t <- torch_tensor(x) # 按前两维求和,同时保留维度方便广播 dim_sum_t <- x_t$sum(dim = 3, keepdim = TRUE) a_t <- x_t / dim_sum_t # 转回R数组 a <- as.array(a_t)
这种方法在数据量很大的时候运算效率远高于基础R的apply系列函数。
内容的提问来源于stack exchange,提问作者McCuys
相关产品推荐
相关产品推荐

