Numpy:评估高于/低于平均值的标准差

2 投票
2 回答
3145 浏览
提问于 2025-04-17 20:22

我想计算一个包含 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可能会稍微快一些(没有经过测试)。

撰写回答