Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.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
Python 沿Numpy阵列轴的质心标准偏差_Python_Python 2.7_Numpy_Standard Deviation_Weighted Average - Fatal编程技术网

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

Python 沿Numpy阵列轴的质心标准偏差,python,python-2.7,numpy,standard-deviation,weighted-average,Python,Python 2.7,Numpy,Standard Deviation,Weighted Average,我试图找到一种性能良好的方法来计算Numpy阵列轴上质量/重心的标准偏差 在公式中,这是(很抱歉未对齐): 我能想到的最好的办法是: 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, a

我试图找到一种性能良好的方法来计算Numpy阵列轴上质量/重心的标准偏差

在公式中,这是(很抱歉未对齐):

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

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
中,我需要纠正从权重之和到值之和的标准化(我想这是一个丑陋的解决方法)<代码>加权标准可能没问题

为了避免XY问题,我仍然要求得到我真正想要的东西,(一个更好的
weighted\u std
),而不是我的
weighted\u com
的更好版本


.astype(float)
是一种安全措施,因为我将把它应用于包含int的直方图,当不在Python 3中或当来自未来的导入除法不活动时,整数除法会导致问题。

您想取向量的平均值、方差和标准偏差
[1,2,3,…,n]
-其中
n
是输入矩阵
A
沿感兴趣轴的维度,权重由矩阵
A
本身给出

具体的说,你想沿着垂直轴考虑这些质量统计中心(<代码>轴= 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=0和axis=1都能正常工作

import numpy as np

def com_stats(A, axis=0):
    A = A.astype(float)    # if you are worried about int vs. float
    n = A.shape[axis]
    m = A.shape[(axis-1)%2]
    r = np.arange(1, n+1)
    R = np.vstack([r] * m)
    if axis == 0:
        R = R.T

    mu = np.average(R, axis=axis, weights=A)
    var = np.average(R**2, axis=axis, weights=A) - mu**2
    std = np.sqrt(var)
    return mu, var, std
比如说,

A = np.array([[1, 1, 0], [1, 2, 1], [1, 1, 1]])
print(A)

# [[1 1 0]
#  [1 2 1]
#  [1 1 1]]

print(com_stats(A))

# (array([ 2. ,  2. ,  2.5]),                   # centre-of-mass mean by column
#  array([ 0.66666667,  0.5       ,  0.25  ]),  # centre-of-mass variance by column
#  array([ 0.81649658,  0.70710678,  0.5   ]))  # centre-of-mass std by column
编辑:

通过使用
numpy.lib.stride\u技巧
:交换行,可以避免在内存中创建
r
的副本来构建
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))
输出:

形状:(10,)
步幅:(8,)
内存中的位置:4299744576
内存大小(字节):80
形状:(1000,10)
步幅:(80,8)
内存中的位置:4304464384
内存大小(字节):80000
形状:(1000,10)
步幅:(0,8)
内存中的位置:4299744576
内存大小(字节):80

关于如何获取跨步
ndarray

的底层数组的内存地址和大小的解释,请参见和。在我提出问题的解决方案之前,它尝试过这样的方法。。。然而,我担心创建(潜在巨大的)
R
矩阵。由于
R
只包含
R
的副本,我们能摆脱复制吗?哦,这是一个非常好的技巧。记忆力好,我想我们现在是平手了。你还看到潜在的差异吗?似乎,我们应该为性能分析我们的解决方案。。。