Numpy:评估高于/低于平均值的标准差
我想计算一个包含 n_par 参数和 n_sample 样本的矩阵中,低于和高于平均值的标准差。到目前为止,我找到的最快的方法是:
stdleft = numpy.zeros_like(mean)
for jpar in xrange(mean.shape[1]):
stdleft[jpar] = p[p[:,jpar] < \
mean[jpar],jpar].std()
这里的 p 是一个形状为 (n_samples, n_par) 的矩阵。有没有更聪明的方法可以做到这一点,而不需要使用 for 循环?我的 n_par 大约是 200,n_samples 大约是 1e8,所以这三行代码执行起来非常慢。
任何建议都将非常有帮助!
谢谢
2 个回答
2
Pandas是你的好帮手。把你的矩阵转换成pandas的DataFrame,然后用合适的方式给这个DataFrame加上索引。可以这样做:
mat = pandas.DataFrame(p)
这段代码是从原来的numpy矩阵p
创建一个DataFrame。接着,我们计算这个DataFrame每一列的平均值。
m = mat.mean()
接下来,创建一个大小为n_par
的数组,里面存放mat
每一列的平均值。最后,用<
这个逻辑操作来索引mat
矩阵,并对结果应用std
函数。
stdleft = mat[mat < m].std()
对于stdright
也是类似的。计算在我的机器上大约需要几分钟。
这是pandas的文档页面:http://pandas.pydata.org/
编辑:根据下面的评论进行了编辑。你可以用原来的p
做几乎相似的索引。
m = p.mean(axis=0)
logical = p < m
logical
是一个和p
同样大小的布尔矩阵。这时候pandas就派上用场了。你可以直接用同样大小的逻辑矩阵来索引pandas的矩阵。而在numpy中这样做稍微有点难。我想循环可能是实现这个的最好方法吧?
for i in range(len(p)):
stdleft[i] = p[logical[:, i], i].std()
2
我理解你的意思是,你想计算每一列中那些低于该列平均值的数值的标准差。
在numpy中,使用掩码数组来处理这个问题是最简单的。
举个例子:
import numpy as np
# 10 samples, 3 columns
p = np.random.random((10, 3))
# Calculate the mean of each column
colmeans = p.mean(axis=0)
# Make a boolean array where our condition is True
mask = p < colmeans
# Find the standard deviation of values in each column below the column's mean.
# For masked arrays, the True values will be masked, so we'll invert the array.
stdleft = np.ma.masked_where(~mask, p).std(axis=0)
你也可以使用pandas
来实现这个,正如@SudeepJuvekar提到的那样。整体性能应该差不多,但在这个特定操作上,pandas可能会稍微快一些(没有经过测试)。