6

我正在尝试编写一个函数,该函数将在二维数组内创建一个 5 像素 x 5 像素的规则网格。我希望某些组合可能会做到这一点numpy.arangenumpy.repeat但到目前为止我还没有运气,因为numpy.repeat只会在同一行重复。

这是一个例子:

假设我想要一个 2d 数组 shape 内的 5x5 网格(20, 15)。它应该看起来像:

array([[ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5],
       [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5],
       [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5],
       [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5],
       [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5],
       [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
       [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
       [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
       [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
       [ 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8],
       [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11],
       [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11],
       [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11],
       [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11],
       [ 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11]])

我意识到我可以简单地使用循环和切片来完成此任务,但我可能会将其应用于非常大的数组,我担心其性能会太慢或不切实际。

谁能推荐一种方法来实现这一点?

提前致谢。

更新

提供的所有答案似乎都运作良好。谁能告诉我哪个对大型阵列最有效?通过大数组,我的意思是它可能是100000 x 100000或更多的15 x 15网格单元大小。

4

3 回答 3

3

Broadcasting is the answer here:

m, n, d = 20, 15, 5
arr = np.empty((m, n), dtype=np.int)
arr_view = arr.reshape(m // d, d, n // d, d)
vals = np.arange(m // d * n // d).reshape(m // d, 1, n // d, 1)
arr_view[:] = vals

>>> arr
array([[ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2],
       [ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2],
       [ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2],
       [ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2],
       [ 0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2],
       [ 3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5],
       [ 3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5],
       [ 3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5],
       [ 3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5],
       [ 3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5],
       [ 6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8],
       [ 6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8],
       [ 6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8],
       [ 6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8],
       [ 6,  6,  6,  6,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8],
       [ 9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11],
       [ 9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11],
       [ 9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11],
       [ 9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11],
       [ 9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11]])
于 2013-10-14T16:10:30.790 回答
3

类似于 Jaime 的回答:

np.repeat(np.arange(0, 10, 3), 4)[..., None] + np.repeat(np.arange(3), 5)[None, ...]
于 2013-10-14T16:25:12.600 回答
2

kron将进行此扩展(正如 Brionius 在评论中也建议的那样):

xi, xj, ni, nj = 5, 5, 4, 3
r = np.kron(np.arange(ni*nj).reshape((ni,nj)), np.ones((xi, xj)))

虽然我还没有测试过,但我认为它比广播方法效率低,但更简洁,更容易理解(我希望)。它可能效率较低,因为:1)它需要一个数组,2)它xi*xj乘以 1,以及 3)它做了一堆 concat。

于 2013-10-14T17:00:59.733 回答