【问题标题】:Function to get top left and bottom right indexes of nonzero elements in an array获取数组中非零元素的左上和右下索引的函数
【发布时间】:2020-08-17 02:50:59
【问题描述】:

所以目标是编写一个函数,给出数组中一组非零元素的左上和右下索引。数组中的两组不能相邻。如果组只存在一个元素,则左上角和右下角的索引是相同的。很容易获得一个获取所有非零元素索引的函数,但我似乎无法过滤它,所以只保留左上角和右下角的索引。 这是我已经得到的功能:

import numpy as np
def get_indexes(A):
    M,N = A.shape
    pos = []
    for i in range(M):
        for j in range(N):
            if A[i,j]!=0:
                pos.append((i,j,A[i,j]))
    return pos

以下是给定数组的示例:

A= np.array([[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0],
[6, 6, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]])

感谢您的帮助!

【问题讨论】:

  • numpy 也有一个nonzero function,您可以使用它来获取非零元素。你的阵列总是二维的吗?您可以将它们视为图像,将非零元素视为对象。如果这听起来不错,我可以提供帮助,但我不确定这是否是一种简单的方法。
  • 是的,数组总是二维的。我知道非零函数,但这不是我被困的地方。我只需要非零元素的左上角和右下角索引

标签: python arrays numpy


【解决方案1】:

我以for循环的递增顺序遍历矩阵以找到非零元素的左上角索引,并获得非零元素的右下角索引我遍历for循环的递减顺序。 代码如下:

import numpy as np

A= np.array([
[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0],
[6, 6, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]])


def getting_top_left_indexes(A):
    break_condition = False
    M,N = A.shape
    pos = []
    for i in range(M):
        if break_condition == True:
            break
        for j in range(N):
            if A[i,j]!=0:
                pos.append((i,j,A[i,j]))
                break_condition = True
                break
    return pos

def getting_bottom_right_indexes(A):
    break_condition = False
    M,N = A.shape
    pos = []
    for i in range(M-1, 0, -1):
        if break_condition == True:
            break
        for j in range(N-1, 0, -1):
            if A[i,j]!=0:
                pos.append((i,j,A[i,j]))
                break_condition = True
                break
    return pos


top_left_indexes = getting_top_left_indexes(A)
bottom_right_indexes = getting_bottom_right_indexes(A)

编辑:我编辑了关于您的解释的答案。 这里更新的代码:

import numpy as np

A= np.array([
[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 9, 0, 0, 0],
[0, 7, 7, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 0, 0],
[6, 6, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 5, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0]])

def get_indexes(A):
    M,N = A.shape
    pos = []
    for i in range(M):
        for j in range(N):
            if A[i, j] != 0:
                pos.append((i,j,A[i,j]))
    return pos

def filtering_indexes(indexes):
    filtered_list = []
    sorted_indexes = sorted(indexes, key=lambda x: x[-1])
    top_left_index = sorted_indexes[0]
    for i in range(0, len(sorted_indexes)):
        if sorted_indexes[i][2] == top_left_index[2]:
            pass
        else:
            filtered_list.append(sorted_indexes[i-1])
            top_left_index = sorted_indexes[i]
            filtered_list.append(top_left_index)

    if sorted_indexes[i][2] == top_left_index[2]:
        filtered_list.append(sorted_indexes[i])
    return filtered_list

indexes = get_indexes(A)
filtered_indexes = filtering_indexes(indexes)

【讨论】:

  • 是的,就是做你想做的事。但是我需要每个非零组的索引,而不仅仅是左上角的那个。不过我很感激。
  • @V_Buffalo 我认为我们需要获取左上角和右下角的索引。我更新了我的答案
  • @V_Buffalo 欢迎您。如果有帮助,你能接受它作为解决方案吗?
【解决方案2】:

这是另一种查找顶部和底部的方法。这个想法是在带有 0 的 padded 版本的 A 的行和列上使用 diff。一旦找到顶部,迭代以在行或列的其余部分找到带有 argmax 的底部每个顶部为 0。

#pad around A with 0s to avoid boundary effect
A_ = np.pad(A,((1,1),(1,1)),constant_values=0)

#get the position of the tops in A
tops = np.array(np.where((np.diff(A_, n=1, axis=1)[1:]>0) 
                          &(np.diff(A_, n=1, axis=0)[:, 1:]>0))).T
print(tops)
# [[0 1] # row 0, col 1 is the top of group 7
#  [1 5] # row 1, col 5 is the top of group 9
#  [5 6] # ...
#  [6 0]
#  [7 4]]

# get the bottom for each top 
bottoms = tops - 1 + np.array(
    [((A_[row_top:, col_top]==0).argmax(), 
      (A_[row_top, col_top:]==0).argmax())
     for (row_top, col_top) in (tops+1)]) #+1 is because A_ is padded version of A
print(bottoms)
# [[4 2] #row 4 col 2 is the bottom of group 7
#  [3 5] #...
#  [5 6]
#  [6 1]
#  [7 5]]

根据你想要的结果,这里是一个包含组值的数组,假设它们是常量。

# create an array with all data with last column being the value of the group if necessary
res = np.hstack([tops, bottoms, A[tops[:,0], tops[:,1]][:,None]])
print(res)
# [[0 1 4 2 7] # group top at row 0 col 1 bottom at row 4 col 2 and value 7
#  [1 5 3 5 9] #...
#  [5 6 5 6 1]
#  [6 0 6 1 6] 
#  [7 4 7 5 5]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 1970-01-01
    相关资源
    最近更新 更多