【问题标题】:R: normalize (mean=0, variance=1) function that can be used with apply() on arbitrary axisR:可在任意轴上与 apply() 一起使用的标准化(均值 = 0,方差 = 1)函数
【发布时间】:2014-03-03 09:47:45
【问题描述】:

我想要一个沿给定轴标准化数组的函数。基本上,我希望能够写的是:

apply(X, axis, normalize)

它应该按行、列、...或沿第 n 个维度对我的数组进行规范化。

这听起来像是一个很常见的问题,但 R 似乎无法在不使用 quirks 的情况下解决它。

考虑以下矩阵和函数:

> m = matrix(1:4,nrow=2,dimnames=list(c('a','b'),c('x','y')))
> m
  x y
a 1 3
b 2 4

normalize=function(X) {
    X = X - mean(X)
    X = X/sd(X)
    return(X)
}

如果我将apply() 与轴号一起使用,结果如下:

> apply(m, 2, normalize)
           x          y
a -0.7071068 -0.7071068
b  0.7071068  0.7071068

一切正常

> apply(m, 1, normalize)
           a          b
x -0.7071068 -0.7071068
y  0.7071068  0.7071068

这里,矩阵已经转置(这是我不想要的)。我想保留 n 维数组的原始维度。

不起作用的可能答案是:

  • 使用t(),跨行应用,然后转回:这不适用于多维数组
  • 使用y包的x函数:可能同上
  • 为每个维度写一个if子句:解决方案应该是普遍适用的,而不仅仅是一些硬编码的情况

编辑:根据罗兰的建议,我将使用以下函数代替apply

array_apply = function(X, along, FUN) {
    X = as.array(X)
    ndim = c(1:length(dim(X)))

    preserveAxes = ndim[ndim != along]
    orderAxes = c(along, preserveAxes)

    X = apply(X, preserveAxes, FUN)
    return(aperm(X, orderAxes))
}

其行为方式如下:

> m = matrix(1:4,nrow=2,dimnames=list(c('a','b'),c('x','y')))

> array_apply(m,1,normalize)
       x          y
a -0.7071068 -0.7071068
b  0.7071068  0.7071068

> array_apply(m,2,normalize)
       x         y
a -0.7071068 0.7071068
b -0.7071068 0.7071068

【问题讨论】:

    标签: r multidimensional-array normalization


    【解决方案1】:

    让我们用一个更好的例子来看看会发生什么:

    m = matrix(c(1,2,7,10,12,18),nrow=2)
    #     [,1] [,2] [,3]
    #[1,]    1    7   12
    #[2,]    2   10   18
    apply(m, 1, scale)
    #            [,1] [,2]
    #[1,] -1.02888681   -1
    #[2,]  0.06052275    0
    #[3,]  0.96836405    1
    

    如您所见,scale 应用于矩阵行,结果向量组合为结果矩阵的列。

    apply(m, 2, scale)
    #           [,1]       [,2]       [,3]
    #[1,] -0.7071068 -0.7071068 -0.7071068
    #[2,]  0.7071068  0.7071068  0.7071068
    

    现在scale 应用于矩阵列,但结果向量再次组合为结果矩阵的列。这确实记录在help("apply")

    如果每次调用 FUN 返回一个长度为 n 的向量,则 apply 返回 如果 n > 1,则为维度为 c(n, dim(X)[MARGIN]) 的数组。

    编辑:

    如果你这样做,你可以避免这个问题:

    (m-apply(m,1,mean))/apply(m,1,sd)
              [,1]       [,2]      [,3]
    [1,] -1.028887 0.06052275 0.9683641
    [2,] -1.000000 0.00000000 1.0000000
    

    【讨论】:

    • 所以基本上,apply 不支持每个元素的向量结果?如果有,有没有这样的功能?
    • 我不知道你是怎么得出这个结论的。
    • 啊,我的错。感谢您的澄清,但它并没有解决根本问题。
    • 为什么不呢?如果您按行应用或将aperm 用于数组,只需转置结果即可。
    • 你不能在多维数组上转置,正如问题中已经说明的那样。然后我会看看aperm..
    猜你喜欢
    • 2012-03-27
    • 1970-01-01
    • 2014-11-23
    • 2017-10-09
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多