gpt4 book ai didi

python - 减去 ndarray 的最后一个轴

转载 作者:行者123 更新时间:2023-12-01 08:15:32 27 4
gpt4 key购买 nike

I want to subtract all values in a[nn,...,0] by b[nn] while keeping the original structure of the array a.

<小时/>

我在 ndnumpy 数组的索引和元素减法方面遇到问题。就我而言,数组 a 有 6 个维度

In[]: a.shape
Out[]: (101, 256, 1, 3, 1, 10)

为了保持一致性,最低维度 N=0 有 10 个元素,最高维度 N=5 有 101 个元素。

我还有一个一维数组b,它的大小与最高的相同尺寸为a

In[]: b.shape
Out[]: (101,)

我想从 a 中减去 b,使得 b 中的第 nn 个元素是从值 a[nn,...,0] 中减去。我知道我可以使用 for 循环来做到这一点,但也应该可以以我可以使用类似的方式来广播 b

In[]: c= a[:,...,0]-b[somehow broadcastet or reshaped]
In[]: c.shape()
Out[]: (101, 256, 1, 3, 1, 10)

最佳答案

您确实可以利用 broadcasting 来做到这一点.

让我们首先生成一些随机的 ndarrays指定形状的形状,以检查最终尺寸是否符合预期:

a = np.random.rand(101, 256, 1, 3, 1, 10)
b = np.random.rand(101)

在这种情况下,您必须添加 a.ndim尺寸为b这样 b 中的每个值减去a最后一个维度中的每个值。遵循this的想法帖子我们可以加起来 a.ndim使用 np.reshape 以更简洁的方式创建新尺寸如下:

b = b.reshape((-1,) + (1,)*(a.ndim-1))
print(b.shape)
# (101, 1, 1, 1, 1, 1)

现在我们可以减去 b来自a根据要求执行以下操作:

a[..., 0, None] = a[..., 0, None] - b.reshape((-1,) + (1,) * (a.ndim-1))

如果我们检查 a 的形状:

print(a.shape)
# (101, 256, 1, 3, 1, 10)
<小时/>

详细信息

以下是对之前答案中可能出现的一些问题的一些解释。让我们考虑以下更简单的示例:

a = np.array([[1,2,3],[4,5,6]])
print(a)
array([[1, 2, 3],
[4, 5, 6]])
print(a.shape)
# (2, 3)

b = np.array([1,1])[:,None]
array([[1],
[1]])
print(b.shape)
# (2, 1)

因此,对于这个示例,我们可以应用与上述解决方案相同的逻辑:

a[:,0,None] = a[:,0,None] - b

array([[0, 2, 3],
[3, 5, 6]])

通过检查结果数组,如预期的那样b已从 a 中减去在沿最后一个轴的第一个索引上,因此是所有行中的第一列。

<小时/>

所以第一点,

Why do we have to add a new axis in a for subtraction?

需要向 a 添加新轴给定形状 b 。请注意b是一个二维数组array([[1],[1]]) ,所以如果你直接从 a 中减去它,你会得到:

a[..., 0] - b
array([[0, 3],
[0, 3]])

所以,这里发生的是较小的数组,即第一项,它只是一个 1D查看切片 a , array([1, 4]) ,已在更大的数组中广播,以便它们具有兼容的形状。

如果形状为b,则不需要这样做。相反 (2,) :

b = np.array([1,1])
a[:,0] - b
# array([0, 3])

但是由于 b 的方式在已定义的实际解决方案中,它具有与 a 相同的尺寸。 。所以为了获得正确的输出,我们必须添加一个新的轴a :

a[:,0,None] - b
array([[0],
[3]])

这样我们就得到了正确的输出。

<小时/>

With the method above it doesn't seem possible to assign the difference to a new array acting as a "corrected copy" of a?

这个问题的答案可以通过看减法的结果来理解:

c = a[:,0,None] - b
c.shape
(2, 1)

所以这里a[:,0,None]就是所谓的 a 的“切片 View ” 。因此请注意,通过将此结果分配给 c ,您只保存实际的 sliced wiewa ,不是整个ndarray 。如果要修改a在实际切片的相同位置上,您必须将其分配给 a 的相同切片 View ,所以:

a[:,0,None] = a[:,0,None] - b
print(a.shape)
# (2, 3)

现在结果确实达到了预期的输出,因为我们只修改了 a 的一部分。如果您确实想保存原始副本 ndarray你可以使用 np.copy ,这将返回实际副本而不是 a 的切片,然后将结果分配给“更正的副本”:

a_c = np.copy(a)
a_c[:,0,None] = a[:,0,None] - b

关于python - 减去 ndarray 的最后一个轴,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55005874/

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