获取矩阵

时间:2016-11-12 19:18:49

标签: python python-2.7

我需要点子,这不是作业.......

我有以下矩阵,我如何获得重复数字的坐标,

imagen http://image.prntscr.com/image/24ef1e12db9542f9b171170aaefa5751.png

重复[[[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

由于

编辑:

预期产出:

组1,分开2,分开3和仅2

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

3 个答案:

答案 0 :(得分:2)

效率不高,因为测试数组多次用于逻辑比较检查,但大多数循环被推送到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)]

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

答案 1 :(得分:1)

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

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初始化为None,其长度为max,通过遍历输入矩阵(O(N ^ 2))找到。关键观察 - 如果memo中的特定数字有多对坐标,则我们发现重复。

答案 2 :(得分:1)

这是一个非Numpy解决方案。它使用itertools.groupby将坐标分成具有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)]])