Numpy环形阵列

6za6bjd0  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(112)

我一直在尝试学习numpy一段时间,并决定编写一些复杂的练习来验证我是否理解了一切,其中有一个对我来说似乎有点奇怪。
我们的目标是编写一个只使用numpy库和numpy索引的函数(没有for/while循环,没有if语句),这将使矩阵中的所有偶数环归零。
首先,我试图得到一个给定的环,这里有一个函数:这里m是矩阵,l是环的水平,0是外环

def get_ring(m, l):
    n = m.shape[0]
    return np.concatenate((m[l:n-l, l:n-l], m[(l+1):n-l, -(l+1)], m[-(l+1), -(l+2):l:-1], m[n-(l+1):l:-1, l]))

然后,我进一步编写了这个函数,使用np.where和一些逻辑,通过对组成环的4个部分进行oring,将一个环归零。

def zero_ring(m, l):
    n = m.shape[0]
    m[l:n-l, l:n-l] = np.where(np.logical_or(np.logical_or(np.arange(n-l-l)[:, None] == 0, np.arange(n-l-l) == n-l-l-1),
                               np.logical_or(np.arange(n-l-l)[::-1][:, None] == 0, np.arange(n-l-l)[::-1] == n-l-l-1)), 0, m[l:n-l, l:n-l])
    return m

给予你一个例子,这是一个5x 5数组的输出
一个二个一个一个
现在剩下的就是写一个函数来把所有的偶数环归零,但是我不知道如果不使用for循环该怎么做,因为它是立即的。

kgsdhlau

kgsdhlau1#

你的代码有点复杂,我不知道你是否可以在没有任何手动循环的情况下将其扩展到多个环。我认为如果你以分段的方式构建每个环,这将很坚韧实现,但请随时证明我错了:)。
也就是说,我确实知道一种替代的、有趣的方法来构建环状结构。考虑数组:

[3, 2, 1, 0, 1, 2, 3]

以及该数组中每对整数之间的最大值:

3  2  1  0  1  2  3
  /---------------------\
3 | 3  3  3  3  3  3  3 |
2 | 3  2  2  2  2  2  3 |
1 | 3  2  1  1  1  2  3 |
0 | 3  2  1  0  1  2  3 |
1 | 3  2  1  1  1  2  3 |
2 | 3  2  2  2  2  2  3 |
3 | 3  3  3  3  3  3  3 |
  \---------------------/

你要找的环正好是这个数组中的偶数和奇数元素!
你可以用np.abs + np.arange来创建这样一个任意大小的1D数组:
一个二个一个一个
并使用广播或np.maximum.outer创建两个此类数组之间的成对最大值。为了区分偶数和奇数环,您可以使用2取模。

def ring_mask(h, w):
    rows = center(h)
    cols = center(w)

    return (np.maximum.outer(rows, cols) % 2).astype(bool)

最后,将掩码与np.where结合使用:

def zero_rings(arr):
    mask = ring_mask(*arr.shape)
    return np.where(~mask, arr, 0)
import numpy as np

arr = np.arange(1, 82).reshape(9, 9)
out = zero_rings(arr)

输出:

array([[ 1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10,  0,  0,  0,  0,  0,  0,  0, 18],
       [19,  0, 21, 22, 23, 24, 25,  0, 27],
       [28,  0, 30,  0,  0,  0, 34,  0, 36],
       [37,  0, 39,  0, 41,  0, 43,  0, 45],
       [46,  0, 48,  0,  0,  0, 52,  0, 54],
       [55,  0, 57, 58, 59, 60, 61,  0, 63],
       [64,  0,  0,  0,  0,  0,  0,  0, 72],
       [73, 74, 75, 76, 77, 78, 79, 80, 81]])

PS:你可能需要也可能不需要反转掩码(或者在% 2之前加1),这取决于你认为哪些环是偶数,哪些是奇数。

相关问题