Numpy:np.repeat和np.broadcast_to之间的差异

问题描述 投票:1回答:2

1°为什么以下代码返回False?我以为np.broadcast_to会像np.repeat一样增加数组的dimensin。

2°我可以用np.repeat再现np.broadcast_to给出的结果吗?

import numpy as np
n = 100
d = 10
A = np.random.uniform(size=(n,d))
np.all(np.broadcast_to(A.reshape(n,1,d),(n,d-1,d))==np.repeat(A,d-1).reshape(n,d-1,d))

3°更笼统,对于给定的形状(n,d)的射线A,我如何用np.repeat(A,k).reshape((n,k,d))再现np.broadcast_to

python numpy
2个回答
1
投票

np.broadcast_to为您提供array-wise重复,而np.repeat为您提供element-wise重复行为,请参阅文档[1][2]中的示例。为了在这种情况下获得均等的输出,可以按如下方式更改重塑:

import numpy as np
n = 100
d = 10
A = np.random.uniform(size=(n,d))

A_bc = np.broadcast_to(A.reshape(n*d, 1), (n*d, d-1)).reshape(n, d-1, d)
A_rp = np.repeat(A, d-1).reshape(n, d-1, d)

np.all(A_rp == A_bc)
# True

注意:尽管timeit表示broadcast_to选项稍微快一些,但我不确定它实际上是否更节省内存。


1
投票

这里发生了很多事情,使用包含少量标志值的数组来识别问题会更容易。这是一个易于使用的示例:

arr = np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) # n = 2, d = 4

让我们看看broadcast_to的作用:

broadcast_to

您可以使用>>> A.reshape(n, 1, d) array([[[1, 2, 1, 2]], [[3, 4, 3, 4]]]) >>> arr.broadcast_to(_, (n, d - 1, d)) array([[[1, 2, 1, 2], [1, 2, 1, 2], [1, 2, 1, 2]], [[3, 4, 3, 4], [3, 4, 3, 4], [3, 4, 3, 4]]]) tiletile获得功能相似的数组。主要区别在于stack不会在新维度中复制数据。相反,它会调整步幅,以使数组看起来具有正确的大小(如果您不小心,可能会导致意外行为,例如,写入缓冲区):

    stack

  • concatenate
  • concatenate
  • 现在让我们看一下broadcast_to

    np.tile(arr.reshape(n, 1, d), (1, d - 1, 1))

    这是扁平化的数组,其每个元素重复np.stack([arr] * (d - 1), axis=1)次。显然,此处的重塑将与广播/平铺的版本不同:

    np.concatenate([arr.reshape(n, 1, d)] * (d - 1), axis=1)

    显然,逐元素重复与广播不同。但是,如果正确使用repeat关键字,则实际上可以得到正确的结果:

    repeat

    [如果您想采用另一种方法,并且将数据包装在较短的行中,则可以使用>>> np.repeat(arr, d - 1)
    array([1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4])
    d - 1的组合重新解释尺寸:

    >>> _.reshape(n, d - 1, d) array([[[1, 1, 1, 2], [2, 2, 1, 1], [1, 2, 2, 2]], [[3, 3, 3, 4], [4, 4, 3, 3], [3, 4, 4, 4]]])

    这里是转换的演练:

    axis

  • © www.soinside.com 2019 - 2024. All rights reserved.