Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy矩阵中相邻元素的有效识别_Python_Numpy_Scipy - Fatal编程技术网

Python numpy矩阵中相邻元素的有效识别

Python numpy矩阵中相邻元素的有效识别,python,numpy,scipy,Python,Numpy,Scipy,我有一个100乘100的矩阵。该矩阵主要由零填充,但也包含一些整数。例如: [0 0 0 0 0 0 0 1] [0 2 2 0 0 0 0 0] [0 0 2 0 0 0 0 0] False [0 0 0 0 0 0 0 0] [0 3 3 0 0 0 0 0] 识别矩阵是否包含任意数量的不同类型的相邻整数的最有效方法是什么? 上面的示例将返回False。下面是一个真实的示例,其中显示了包含邻接的行: [0 0 0 0 0 0 0 1] [0 2 2 1 1 0 0 0] <-

我有一个100乘100的矩阵。该矩阵主要由零填充,但也包含一些整数。例如:

[0 0 0 0 0 0 0 1]
[0 2 2 0 0 0 0 0]
[0 0 2 0 0 0 0 0]  False
[0 0 0 0 0 0 0 0]
[0 3 3 0 0 0 0 0]
识别矩阵是否包含任意数量的不同类型的相邻整数的最有效方法是什么?

上面的示例将返回False。下面是一个真实的示例,其中显示了包含邻接的行:

[0 0 0 0 0 0 0 1]
[0 2 2 1 1 0 0 0]   <----  True
[0 0 2 0 0 0 0 0]  
[0 0 0 0 0 0 0 0]
[0 3 3 0 0 0 0 0]
我不需要确定邻接的位置,只需要确定它是否存在

目前,我最擅长的就是找到矩阵中的每个非零元素,然后检查其4个侧面元素


感谢您提供的所有精彩答案。

查看您的问题描述,检查每个可能的非零整数值在数组中的位置,并查看是否存在交点,可能不需要太多计算工作。现在,这通常有些过分,但在您的规模上可能会奏效:您可以获得每个整数集合的索引,并使用
scipy.space.distance.cdist
计算它们的距离。我确信一些基于
diff
或其他东西的智能解决方案更有效,但我还是很开心:

import numpy as np
from scipy.spatial.distance import cdist
from itertools import combinations

M1 = np.array(
[[0,0,0,0,0,0,0,1],
 [0,2,2,1,1,0,0,0],  
 [0,0,2,0,0,0,0,0],
 [0,0,0,0,0,0,0,0],
 [0,3,3,0,0,0,0,0]])

M2 = np.array(
[[0,0,0,1,1,1,1,1],
 [0,2,2,0,1,0,0,0],
 [0,0,2,0,0,0,0,0],  
 [0,3,0,0,0,0,0,0],
 [3,3,3,0,0,0,0,0]])

def overlaps_eh(M):
    uniques = np.delete(np.unique(M),0) # get integers present
    unival_inds = [np.transpose(np.where(M==unival)) for unival in uniques]
    # unival_inds[k] contains the i,j indices of each element with the kth unique value

    for i1,i2 in combinations(range(len(unival_inds)),2):
        if np.any(cdist(unival_inds[i1],unival_inds[i2],'cityblock')==1):
            return True
    # if we're here: no adjacencies
    return False
首先,我们将非零唯一矩阵元素收集到数组
uniques
。然后,对于每个唯一值,我们找到输入数组中具有该值的每个元素的
i,j
索引。然后,我们检查每对唯一值(使用
itertools.compositions
生成),并使用
scipy.space.distance.cdist
测量每对矩阵元素的成对距离。使用曼哈顿距离,如果任何一对元素的距离为1,则它们是相邻的。因此,如果这些距离中的任何一个为1,我们只需返回
True
,否则我们将返回
False

以下是使用


在最后一行,
diff
应用于屏蔽数组(忽略零个条目);
diff
中的非零项表示数组
a
中相邻的不同非零项。变量
adjaccies
将具有邻接总数(可能您只想知道它是否为0)。在上面的示例中,它是1

这里有一种方法可以大量使用只关注性能的视图切片-

def distinct_ints(a):
    # Mask of zeros, non-zeros as we would use them frequently
    zm = a==0
    nzm = ~zm

    # Look for distint ints across rows
    row_thresh = (nzm[:,1:] & zm[:,:-1]).sum(1)
    row_out = ((nzm[:,1:] & (a[:,1:] != a[:,:-1])).sum(1)>row_thresh).any()

    # Look for distint ints across cols
    col_thresh = (nzm[1:] & zm[:-1]).sum(0)
    col_out = ((nzm[1:] & (a[1:] != a[:-1])).sum(0)>col_thresh).any()

    # Any from rows or cols
    out = row_out | col_out
    return out
如果您可以使用,这将非常容易使用,并且:

标签
默认为标签相邻值不同于0,不带对角线。然后,理解将与标签关联的所有值传递给helper函数,该函数检查是否存在多个唯一值。最后,它检查任何标签是否有多个值并返回该值

要在测试输入阵列上测试此功能,请执行以下操作:

arr1 = np.array([[0,0,0,0,0,0,0,1],
                 [0,2,2,1,1,0,0,0],  
                 [0,0,2,0,0,0,0,0],
                 [0,0,0,0,0,0,0,0],
                 [0,3,3,0,0,0,0,0]])

arr2 = np.array([[0,0,0,1,1,1,1,1],
                 [0,2,2,0,1,0,0,0],
                 [0,0,2,0,0,0,0,0],  
                 [0,3,0,0,0,0,0,0],
                 [3,3,3,0,0,0,0,0]])

arr3 = np.array([[0,0,0,0,0,0,0,1],
                 [0,2,2,0,0,0,0,0],
                 [0,0,2,0,0,0,0,0],  
                 [0,0,0,0,0,0,0,0],
                 [0,3,3,0,0,0,0,0]])

>>> adjacent_diff(arr1)
True
>>> adjacent_diff(arr2)
False
>>> adjacent_diff(arr3)
False

使用
numpy.diff
可以实现这一点,但是,不应该考虑零的事实使事情变得复杂了一点

可以将零设置为足够大或足够小的值,以避免出现问题:

a[a == 0] = -999
或者使用浮点数组并将其设置为
nan
inf

a[a == 0] = numpy.nan
然后只需在每个方向上查找
1
的一阶差:

numpy.any(numpy.abs(numpy.diff(a, axis=0)) == 1) or numpy.any(numpy.abs(numpy.diff(a, axis=1)) == 1)

在不发布完整答案的情况下,我将从带有axis参数的
numpy.diff
开始。谢谢,这将显著减少搜索区域。能否添加检查每个元素的代码。这可能会消除一些关于测试的模糊性。
a[a == 0] = -999
a[a == 0] = numpy.nan
numpy.any(numpy.abs(numpy.diff(a, axis=0)) == 1) or numpy.any(numpy.abs(numpy.diff(a, axis=1)) == 1)