Python 获取矩阵中重复数字的坐标

Python 获取矩阵中重复数字的坐标,python,python-2.7,Python,Python 2.7,我需要想法,这不是家庭作业 我有下面的矩阵,如何得到重复数的坐标 重复项[[0,0],[1,0],[2,0],[0,1],[0,2],[1,2],[1,3],[2,2],[[0,3],[0,4],…] 瞬时代码: n = [ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ] coordinates = [[-1,0],[0,1],[1,0],[0,-1]] i = 0 while i < len(n): j = 0 fila = []

我需要想法,这不是家庭作业

我有下面的矩阵,如何得到重复数的坐标

重复项[[0,0],[1,0],[2,0],[0,1],[0,2],[1,2],[1,3],[2,2],[[0,3],[0,4],…]

瞬时代码:

n = [ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ]

coordinates = [[-1,0],[0,1],[1,0],[0,-1]]
i = 0
while i < len(n):
    j = 0
    fila = []
    while j < len(n[0]):
        for coordinate in coordinates:
            X = i + coordinate[0]
            Y = j + coordinate[1]
            if X >= 0 and X < len(n) and Y >= 0 and Y < len(n[0]):
                # I tried with two for in here but its not efficient
        j+=1
    i+=1
n=[[1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3]]
坐标=[-1,0],[0,1],[1,0],[0,-1]]
i=0
而i=0且X=0且Y
谢谢

编辑:

预期产出:

第1组、第2组、第3组和仅第2组


重复[[0,0],[1,0],[2,0],[0,1],[0,2],[1,2],[1,3],[0,4],[1,1],[2,1],[1,4],[2,3],[2,4],[[2,3],[2,4]

根据您提供给示例的输出,我提出了以下解决方案:

import sys

def findMax(n, m, mat):
    max = -sys.maxint - 1
    for i in xrange(n):
        for j in xrange(m):
            if mat[i][j] > max:
                max = mat[i][j]
    return max


def doIt(mat):
    n, m = len(mat), len(mat[0])
    max_val = findMax(n, m, mat)
    memo = [None] * (max_val + 1)
    for i in xrange(n):
        for j in xrange(m):
            if memo[mat[i][j]] is None:
                memo[mat[i][j]] = [(i, j)]
            else:
                memo[mat[i][j]].append((i, j))
    return {i: item for i, item in enumerate(memo) if item is not None and len(item) > 1}

if __name__ == '__main__':
    n = [ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ]
    print doIt(n)

memo
是一个列表,其中索引指示一个可能重复的数字,相应的值是坐标列表。最初
memo
是通过遍历输入矩阵(O(N^2))找到的长度
max
None
初始化的.Key observation-如果在
备忘录
中有多对特定数字的坐标,则我们发现了一个重复。

根据您提供给示例的输出,我提出了以下解决方案:

import sys

def findMax(n, m, mat):
    max = -sys.maxint - 1
    for i in xrange(n):
        for j in xrange(m):
            if mat[i][j] > max:
                max = mat[i][j]
    return max


def doIt(mat):
    n, m = len(mat), len(mat[0])
    max_val = findMax(n, m, mat)
    memo = [None] * (max_val + 1)
    for i in xrange(n):
        for j in xrange(m):
            if memo[mat[i][j]] is None:
                memo[mat[i][j]] = [(i, j)]
            else:
                memo[mat[i][j]].append((i, j))
    return {i: item for i, item in enumerate(memo) if item is not None and len(item) > 1}

if __name__ == '__main__':
    n = [ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ]
    print doIt(n)

memo
是一个列表,其中索引指示一个可能重复的数字,相应的值是坐标列表。最初
memo
是通过遍历输入矩阵(O(N^2))找到的长度
max
None
初始化的.Key observation-如果在
备忘录中有多对特定数字的坐标,则我们发现了一个重复。

效率不高,因为测试数组多次用于逻辑比较检查,但大多数循环都被推到C级。 同时,它展示了一些有趣的方法,如果您有类似的功能可以执行,您可以探索这些方法

import scipy.ndimage as nd    
import numpy as np

n = np.array([ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ], dtype=np.int)

def print_coord(val, pos, shape):
    print("{}: {}".format(val[0], list(zip(*np.unravel_index(pos, dims=shape)))))
    return 0

for val in np.unique(n):
    labelled_array, num_features = nd.label(n == val)
    nd.labeled_comprehension(n, labelled_array, [1,2,3], 
        lambda v, p: print_coord(v, p, shape=n.shape), float, 0, True)
输出:

1: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (1, 3), (2, 0), (2, 2)]
2: [(1, 1), (2, 1)]
2: [(1, 4)]
3: [(0, 3), (0, 4)]
3: [(2, 3), (2, 4)]

当您不想保留与该坐标列表匹配的标签时,当然可以将结果附加到列表中。

效率不高,因为测试数组多次用于逻辑比较检查,但大多数循环都被推到C级。 同时,它展示了一些有趣的方法,如果您有类似的功能可以执行,您可以探索这些方法

import scipy.ndimage as nd    
import numpy as np

n = np.array([ [1,1,1,3,3],[1,2,1,1,2],[1,2,1,3,3] ], dtype=np.int)

def print_coord(val, pos, shape):
    print("{}: {}".format(val[0], list(zip(*np.unravel_index(pos, dims=shape)))))
    return 0

for val in np.unique(n):
    labelled_array, num_features = nd.label(n == val)
    nd.labeled_comprehension(n, labelled_array, [1,2,3], 
        lambda v, p: print_coord(v, p, shape=n.shape), float, 0, True)
输出:

1: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (1, 3), (2, 0), (2, 2)]
2: [(1, 1), (2, 1)]
2: [(1, 4)]
3: [(0, 3), (0, 4)]
3: [(2, 3), (2, 4)]

当然,当您不想保留与该坐标列表匹配的标签时,您可以将结果附加到列表中。

这里有一个非Numpy解决方案。它用于将坐标分离到具有在
n
中共享相同值的列表中,然后将其分离到由相邻元素组成的子列表中

from itertools import product, groupby

n = [
    [1, 1, 1, 3, 3],
    [1, 2, 1, 1, 2],
    [1, 2, 1, 3, 3],
]

# Return a value from `n` given a coordinate tuple
def keyfunc(t):
    y, x = t
    return n[y][x]

# Make a list of coordinate tuples. 
# This code assumes that all rows in `n` have the same length
a = list(product(range(len(n)), range(len(n[0]))))

# Sort coordinates by the corresponding value in `n`
a.sort(key=keyfunc)

#Split the sorted coordinates into lists that share the same value...
groups = []
for k, g in groupby(a, key=keyfunc):
    # ... and separate those into sublists consisting of neighbours
    # We must turn g into a proper list
    sublists = []
    for t in list(g):
        y, x = t
        neighbours = [(y-1, x), (y+1, x), (y, x-1), (y, x+1)]
        # Search for a sublist that contains a neighbour of `t`
        for lst in sublists:
            if any(u in lst for u in neighbours):
                lst.append(t)
                break
        else:
            # No sublist of neighbours found, start a new one
            sublists.append([t])
    groups.append((k, sublists))

for row in groups:
    print(row)
输出

(1, [[(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (1, 3), (2, 0), (2, 2)]])
(2, [[(1, 1), (2, 1)], [(1, 4)]])
(3, [[(0, 3), (0, 4)], [(2, 3), (2, 4)]])

这是一个非Numpy的解决方案。它用于将坐标分离到具有在
n
中共享相同值的列表中,然后将这些坐标分离到由相邻元素组成的子列表中

from itertools import product, groupby

n = [
    [1, 1, 1, 3, 3],
    [1, 2, 1, 1, 2],
    [1, 2, 1, 3, 3],
]

# Return a value from `n` given a coordinate tuple
def keyfunc(t):
    y, x = t
    return n[y][x]

# Make a list of coordinate tuples. 
# This code assumes that all rows in `n` have the same length
a = list(product(range(len(n)), range(len(n[0]))))

# Sort coordinates by the corresponding value in `n`
a.sort(key=keyfunc)

#Split the sorted coordinates into lists that share the same value...
groups = []
for k, g in groupby(a, key=keyfunc):
    # ... and separate those into sublists consisting of neighbours
    # We must turn g into a proper list
    sublists = []
    for t in list(g):
        y, x = t
        neighbours = [(y-1, x), (y+1, x), (y, x-1), (y, x+1)]
        # Search for a sublist that contains a neighbour of `t`
        for lst in sublists:
            if any(u in lst for u in neighbours):
                lst.append(t)
                break
        else:
            # No sublist of neighbours found, start a new one
            sublists.append([t])
    groups.append((k, sublists))

for row in groups:
    print(row)
输出

(1, [[(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (1, 3), (2, 0), (2, 2)]])
(2, [[(1, 1), (2, 1)], [(1, 4)]])
(3, [[(0, 3), (0, 4)], [(2, 3), (2, 4)]])

您的图形似乎表明空间上未连接的值属于同一组,但您的代码不属于同一组,因为您使用的是一个结构元素,通过该元素可以检查相邻的连接(正方形连接等于1,换句话说,连接类型为“加号”)。您对作为
n
给出的数组的预期输出是什么?矩阵中的值的范围是否有限?如果没有,范围是什么?另外,所有
1
的值都是重复的吗?@martineau max matrix 10 x10@PM2Ring我编辑了这个,谢谢你的图似乎表明空间上不相连的值belong指向同一个组,但您的代码没有,因为您正在使用一个结构元素来检查相邻的连通性(正方形连通性等于1,换句话说是“a加号类型”的连通性)。您对作为
n
给出的数组的预期输出是什么?矩阵中的值的范围是否有限?如果没有,范围是什么?另外,所有
1
的值都是重复的吗?@martineau max matrix 10 x10@PM2Ring我编辑了这个,非常感谢非常感谢