2013-11-15 88 views
7

如果我在numpy数组中有一个N^3三元组数组,我该如何对数组中的所有三元组做一个向量和?出于某种原因,我无法将我的大脑包围在求和指数中。以下是我试过了,但它似乎没有工作时:numpy中多维数组的向量和

a = np.random.random((5,5,5,3)) - 0.5 
s = a.sum((0,1,2)) 
np.linalg.norm(s) 

我预计,随着N增大,如果和正常工作,我应该收敛于0,但我只是不停地越来越大。总和给了我一个正确的形状(3x1)的向量,但显然我必须做错了什么。我知道这应该很容易,但我只是没有得到它。

在此先感谢!

+0

首先尝试一个更简单的情况下, ,例如[[2,4,6,8]]中的[abs((np.random.random(10 ** i)-0.5).sum())的线性情况。你能看到发生了什么事吗? – DSM

+0

那么,它不是总结,而是我的测试案例? (-0.5,0.5)上的一组N个随机数不等于0,因为N - > inf?为什么不?而且,如果我的测试无效,我的总结是否正确? – chadh

+0

您正在计算所得总和向量的大小,使用实数时量值总是正数。参见[wiki页面](http://en.wikipedia.org/wiki/Norm_(数学))。我想你想在[1,2,3,4]]'中使用类似'[(np.random.rand(10 ** N)-0.5).sum()/ 10 ** N的东西来看看相对偏差的收敛。 – Daniel

回答

3

是比较容易分析明白你的问题,如果不是均匀随机数,我们使用标准的正常数字和定性结果可以应用到你的具体情况:现在

>>> a = np.random.normal(0, 1, size=(5, 5, 5, 3)) 
>>> s = a.sum(axis=(0, 1, 2)) 

所以这三个项目的s是125个数字的总和,每个数字都来自标准正态分布。这是一个公认的事实,即将两个正态分布相加给出另一个正态分布,其平均值是平均值的总和,方差是方差之和。因此s中的三个值中的每一个将作为均值为0且标准偏差为sqrt(125)= 11.18的正态分布的随机样本分布。

分布方差增长的事实意味着,即使您多次运行您的代码,您也会看到每个数字的平均值为0,在任何给定的运行中,您更可能看到更大的偏移量从0.

此外,你然后去计算这三个值的标准。将三个标准正态分布平方并将它们加在一起给你一个chi-squared distribution。如果你然后取平方根,你得到chi distribution。前者是比较容易处理,并预测你的三个值的范数的平方的平均值为3 * 125。它肯定似乎是:

>>> mean_norm_sq = 0 
>>> for n in xrange(1000): 
...  a = np.random.normal(0, 1, size=(5, 5, 5, 3)) 
...  s = a.sum(axis=(0, 1, 2)) 
...  mean_norm_sq += np.sum(s**2) 
... 
>>> mean_norm_sq/1000 
374.47629802482447 
+0

谢谢Jaime。这解释了我对涉及的统计数据的困惑。我真的需要更多的统计数据,我也一直被stat-mech弄糊涂。不幸的是,我仍然不能100%确定我正在做我的总和。我的代码的实际目的不是对随机数进行求和,那只是一个(构思欠佳的)单元测试。我正在计算三维海森堡自旋系统的磁化强度,因此是三重态的NxNxN阵列。我的a.sum((0,1,2))是获得我的三胞胎的矢量和的正确方法......从您的答案看来,它可能是。 – chadh

3

作为意见说明,平方和总和应接近于零。通过描述,一组N三维向量听起来像它的形状应该是(N,3)而不是(N,N,N,3),但我可能会误解它。无论哪种方式,这是简单的观察在两种情况下会发生什么:

import numpy as np 

avg_sum = [] 
sq_sum = [] 

N_val = 2**np.arange(15) 
for N in N_val: 
    A = np.random.random((N,3)) - 0.5 
    avg_sum.append(A.sum(axis=1).mean()) 
    sq_sum.append ((A**2).sum(axis=1).mean()) 

import pylab as plt 
plt.plot(N_val, avg_sum, label="Average sum") 
plt.plot(N_val, sq_sum, label="Squared sum") 
plt.legend(loc="best") 
plt.show() 

enter image description here

平均总和变为零,你的直觉期待。