Numpy高效获取矩阵中相邻索引或值的方法

3

假设您有一个包含字符串的矩阵A。

[["a", "A", ""],
 ["A", "a", ""],
 ["a", "", ""]]

目标是找到所有的“正方形”,其中包含正交相邻的大写字母,且不存在正交相邻的小写字母。

结果应该如下所示:

[[True, False, True],
 [False, True, False],
 [True, False, False]]

现在,我所做的是创建一个名为adjSquares的字典,将每个方格的笛卡尔指数与相邻方格的笛卡尔指数链接起来。
每次需要进行上述检查时,我会执行以下操作:
np.reshape([any(isupper(A[i,j] for (i,j) in adjSquares[(row,col)])) and not any(islower(A[i,j] for (i,j) in adjSquares[(row,col)])) for row in range(3) for col in range(3)], (3,3))

有没有一种使用矢量化操作获得相同结果的方法?

2个回答

1

以下是基于2D卷积掩码的示例 -

def getmask_based_on_lettercases(a):
    # Generate "star" kernel wtih zero at center as the kernel
    kernel = np.zeros((3,3),dtype=int)
    kernel[:,1] = kernel[1] = 1
    kernel[1,1] = 0

    # Not empty cells mask
    nE = a!=''

    # Mask of at least one uppercase string neighborhood
    U = (np.char.upper(a)==a) & nE
    upper_and_not_empty = convolve2d(U,kernel,'same')>0

    # Mask of at least one lowercase string neighborhood
    L = (np.char.lower(a)==a) & nE
    lower_and_not_empty = convolve2d(L,kernel,'same')>0

    # Let's fulfil "no orthogonal adjacent lower case letters" case
    return upper_and_not_empty & ~lower_and_not_empty

示例运行 -

In [352]: a
Out[352]: 
array([['a', 'A', ''],
       ['A', 'a', ''],
       ['a', '', '']], dtype='<U1')

In [353]: getmask_based_on_lettercases(a)
Out[353]: 
array([[ True, False,  True],
       [False,  True, False],
       [ True, False, False]])

现在,让我们测试“没有正交相邻小写字母”情况,就像问题中提到的那样,通过将a [2,1]设置为小写字母。
In [354]: a[2,1] = 'a'

In [355]: a
Out[355]: 
array([['a', 'A', ''],
       ['A', 'a', ''],
       ['a', 'a', '']], dtype='<U1')

In [356]: getmask_based_on_lettercases(a)
Out[356]: 
array([[ True, False,  True],
       [False, False, False],
       [False, False, False]])

0

你可以创建另一个数组,其中包含原始数据的小写形式:

dd = np.array([["a","A",""],["A","a",""],["","",""]])
dnew = np.char.lower(dd);

然后您可以检查新数据是否等于旧数据:

dd == dnew

然而,它不能处理空字符,但至少解决方案是矢量化的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接