如何使用numpy计算不规则形阵列的平均值和标准差

时间:2017-06-01 07:41:42

标签: python arrays numpy

我有一个numpy数组,里面有很多不同长度的样本

Samples = np.array([[1001, 1002, 1003],
                    ... ,
                    [1001, 1002]])

我想(元素)减去数组的平均值然后除以数组的标准偏差。类似的东西:

newSamples = (Samples-np.mean(Samples))/np.std(Samples)

除了对不规则形状的阵列不起作用外,

np.mean(样本)导致

unsupported operand type(s) for /: 'list' and 'int'

由于我认为它为每个轴设置了静态尺寸,然后当它遇到不同大小的样本时它无法处理它。使用numpy解决这个问题的方法是什么?

示例输入:

Sample = np.array([[1, 2, 3],
                   [1, 2]])

减去均值后再除以标准差:

Sample = array([[-1.06904497,  0.26726124,  1.60356745], 
                [-1.06904497,  0.26726124]])

2 个答案:

答案 0 :(得分:3)

不要制作不规则的阵列。只是不要。 Numpy无法对它们做很多事情,而且您可能为它们制作的任何代码都会变得不可靠和缓慢,因为numpy不会这样做。它将它们变成object dtypes:

Sample
array([[1, 2, 3], [1, 2]], dtype=object)

几乎没有numpy函数可用。在这种情况下,这些对象是list个对象,这使得您的代码更加混乱,因为您必须在listndarray方法之间切换,或坚持列表安全{{1} } 方法。这是一个灾难的秘诀,因为任何人都会在以后的代码中徘徊(即使你自己忘了)也会在雷区里跳舞。

您可以使用数据处理两件事情,以使工作更好:

第一种方法是索引和展平。

numpy

这保留了i = np.cumsum(np.array([len(x) for x in Sample])) flat_sample = np.hstack(Sample) 中每个样本结尾的索引,同时将样本保持为一维数组

另一种方法是使用i填充一个维度并使用np.nan - 安全功能

nan

为了进行计算,您可以使用m = np.array([len(x) for x in Sample]).max() nan_sample = np.array([x + [np.nan] * (m - len(x)) for x in Sample]) 并执行类似上述操作:

flat_sample

并使用new_flat_sample = (flat_sample - np.mean(flat_sample)) / np.std(flat_sample) 重新创建原始数组(或数组列表,我建议:,请参阅i)。

np.split

或使用new_list_sample = np.split(new_flat_sample, i[:-1]) [array([-1.06904497, 0.26726124, 1.60356745]), array([-1.06904497, 0.26726124])] ,但您需要将nan_samplenp.mean替换为np.stdnp.nanmean

np.nanstd

答案 1 :(得分:2)

@MichaelHackman(发表评论后)。 这很奇怪,因为当我计算整体std和mean然后应用它时,我得到不同的结果(见下面的代码)。

import numpy as np

Samples = np.array([[1, 2, 3],
                   [1, 2]])
c = np.hstack(Samples)  # Will gives [1,2,3,1,2]
mean, std = np.mean(c), np.std(c)
newSamples = np.asarray([(np.array(xi)-mean)/std for xi in Samples])
print newSamples
# [array([-1.06904497,  0.26726124,  1.60356745]), array([-1.06904497,  0.26726124])]

编辑:添加np.asarray(),在Imanol Luengo的优秀评论之后将mean,std计算放在循环之外(谢谢!)