我有一个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]])
答案 0 :(得分:3)
不要制作不规则的阵列。只是不要。 Numpy
无法对它们做很多事情,而且您可能为它们制作的任何代码都会变得不可靠和缓慢,因为numpy
不会这样做。它将它们变成object
dtypes:
Sample
array([[1, 2, 3], [1, 2]], dtype=object)
几乎没有numpy
函数可用。在这种情况下,这些对象是list
个对象,这使得您的代码更加混乱,因为您必须在list
和ndarray
方法之间切换,或坚持列表安全{{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_sample
和np.mean
替换为np.std
和np.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
计算放在循环之外(谢谢!)