gpt4 book ai didi

python - numpy:计算多个非连续轴上的平均值和标准差(第二次尝试)

转载 作者:太空宇宙 更新时间:2023-11-03 19:24:19 25 4
gpt4 key购买 nike

[这篇文章的早期版本完全没有得到回应,因此,如果这是由于缺乏清晰度,我已经重新设计了它,并添加了额外的解释和代码注释。]

我想计算 numpy n 维数组的元素的平均值和标准差,这些数组不对应于单个轴(而是对应于 k> 1 非连续轴),并获取在新的 (n - k + 1) 维数组中收集的结果。

Does numpy include standard constructs to perform this operation efficiently?

下面复制的函数mu_sigma是我解决这个问题的最佳尝试,但它有两个明显的低效之处:1)它需要复制原始数据; 2)它计算平均值两次(因为标准差的计算需要计算平均值)。

mu_sigma 函数采用两个参数:boxaxesbox 是一个 n 维 numpy 数组(又名“ndarray”),而 axes 是一个 k 元组整数,表示(不一定是连续的)盒子的尺寸。该函数返回一个新的 (n - k + 1) 维 ndarray,其中包含在 box 的“hyperslabs”上计算的平均值和标准差由 k 个指定的轴表示。

下面的代码还包括一个 mu_sigma 的实际示例。在此示例中,box 参数是 4 x 2 x 4 x 3 x 4 ndarray float ,axes 参数是元组 (1, 3 )。 (因此,我们有n == len(box.shape) == 5,以及k == len(axes)  == 2.) 此示例输入返回的结果(这里我将其称为发件箱)是一个 4 x 4 x 4 x 2 float 数组。对于索引 ikj 的每个三元组(其中每个索引的范围在集合 {0, 1, 2, 3} 内),元素 outbox[i, j, k, 0] 是 numpy 表达式 box[i, 0:2, j, 0:3, k] 指定的 6 个元素的平均值。同样,outbox[i, j, k, 1] 是相同 6 个元素的标准差。这意味着结果的前 n - k == 3 个维度与 n - k 的索引范围相同 输入 ndarray box 的非轴维度,在本例中为维度 0、2 和 4。

mu_sigma中使用的策略是

  1. 排列维度(使用 transpose 方法),以便函数第二个参数中指定的轴全部放在末尾;其余(非轴)尺寸保留在开头(按原始顺序);
  2. 将轴尺寸折叠为一个(通过使用reshape方法);新的“折叠”维度现在是重构后的 ndarray 的最后一个维度;
  3. 使用最后一个“折叠”维度作为轴计算均值的 ndarray;
  4. 使用最后一个“折叠”维度作为轴计算标准差的 ndarray;
  5. 返回通过连接(3)和(4)中生成的 ndarray 获得的 ndarray


import numpy as np

def mu_sigma(box, axes):
inshape = box.shape

# determine the permutation needed to put all the dimensions given in axes
# at the end (otherwise preserving the relative ordering of the dimensions)
nonaxes = tuple([i for i in range(len(inshape)) if i not in set(axes)])

# permute the dimensions
permuted = box.transpose(nonaxes + axes)

# determine the shape of the ndarray after permuting the dimensions and
# collapsing the axes-dimensions; thanks to Bago for the "+ (-1,)"
newshape = tuple(inshape[i] for i in nonaxes) + (-1,)

# collapse the axes-dimensions
# NB: the next line results in copying the input array
reshaped = permuted.reshape(newshape)

# determine the shape for the mean and std ndarrays, as required by
# the subsequent call to np.concatenate (this reshaping is not necessary
# if the available mean and std methods support the keepdims keyword;
# instead, just set keepdims to True in both calls).
outshape = newshape[:-1] + (1,)

# compute the means and standard deviations
mean = reshaped.mean(axis=-1).reshape(outshape)
std = reshaped.std(axis=-1).reshape(outshape)

# collect the results in a single ndarray, and return it
return np.concatenate((mean, std), axis=-1)

inshape = 4, 2, 4, 3, 4
inbuf = np.array(map(float, range(np.product(inshape))))
inbox = np.ndarray(inshape, buffer=inbuf)
outbox = mu_sigma(inbox, tuple(range(len(inshape))[1::2]))

# "inline tests"
assert all(outbox[..., 1].ravel() ==
[inbox[0, :, 0, :, 0].std()] * outbox[..., 1].size)
assert all(outbox[..., 0].ravel() == [float(4*(v + 3*w) + x)
for v in [8*y - 1
for y in [3*z + 1
for z in range(4)]]
for w in range(4)
for x in range(4)])

最佳答案

从 numpy 2.0 开始,这看起来变得更容易了。

http://projects.scipy.org/numpy/ticket/1234

关于python - numpy:计算多个非连续轴上的平均值和标准差(第二次尝试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8731517/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com