沿Numpy阵列轴与质心的标准偏差

2021-04-11 23:56:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图找到一种性能良好的方法来计算从质心到重心的标准偏差。在

在公式中,这是(对不起,失调):

{1美元^

我能想到的最好的办法是:

def weighted_com(A, axis, weights):
    average = np.average(A, axis=axis, weights=weights)
    return average * weights.sum() / A.sum(axis=axis).astype(float)

def weighted_std(A, axis):
    weights = np.arange(A.shape[axis])
    w1com2 = weighted_com(A, axis, weights)**2
    w2com1 = weighted_com(A, axis, weights**2)
    return np.sqrt(w2com1 - w1com2)

weighted_com中,我需要纠正从权重和到值和的规范化(我想这是一个很难看的解决方法)。weighted_std可能没问题。在

为了避免XY问题,我仍然要求得到我真正想要的东西(一个更好的weighted_std),而不是我的weighted_com的更好版本。在

.astype(float)是一种安全措施,因为我将把它应用于包含int的直方图,当python3中不存在或from __future__ import division不活动时,由于整数除法而导致问题。在

1条回答
网友
1楼 ·

你需要取向量[1, 2, 3, ..., n]-其中n是输入矩阵A沿兴趣轴的维数,权重由矩阵A本身给出。在

具体来说,假设您想考虑这些垂直轴上的重心统计信息(axis=0)-这是与您编写的公式相对应的。对于固定列j,可以这样做

n = A.shape[0]
r = np.arange(1, n+1)
mu = np.average(r, weights=A[:,j])
var = np.average(r**2, weights=A[:,j]) - mu**2
std = np.sqrt(var)

为了将不同列的所有计算放在一起,您必须将r(每列一个)的一组副本堆叠在一起,以形成一个矩阵(我在下面的代码中将其称为R)。稍加小心,您就可以使axis=0axis=1同时工作。在

^{pr2}$

例如

^{3}$

编辑:

通过使用numpy.lib.stride_tricks:交换行,可以避免创建r的内存副本来构建{}

R = np.vstack([r] * m)

上面有

from numpy.lib.stride_tricks import as_strided
R = as_strided(r, strides=(0, r.itemsize), shape=(m, n))

得到的R是一个(跨步)ndarray,其底层数组与r的相同——绝对不会发生任何值的复制。在

from numpy.lib.stride_tricks import as_strided

FMT = '''\
Shape: {}
Strides: {}
Position in memory: {}
Size in memory (bytes): {}
'''

def find_base_nbytes(obj):
    if obj.base is not None:
        return find_base_nbytes(obj.base)
    return obj.nbytes

def stats(obj):
    return FMT.format(obj.shape,
                      obj.strides,
                      obj.__array_interface__['data'][0],
                      find_base_nbytes(obj))

n=10
m=1000
r = np.arange(1, n+1)
R = np.vstack([r] * m)
S = as_strided(r, strides=(0, r.itemsize), shape=(m, n))

print(stats(r))
print(stats(R))
print(stats(S))

输出:

Shape: (10,)
Strides: (8,)
Position in memory: 4299744576
Size in memory (bytes): 80

Shape: (1000, 10)
Strides: (80, 8)
Position in memory: 4304464384
Size in memory (bytes): 80000

Shape: (1000, 10)
Strides: (0, 8)
Position in memory: 4299744576
Size in memory (bytes): 80

归功于this SO answerthis one,它们解释了如何获得跨距ndarray的底层数组的内存地址和大小。在

相关问题