【问题标题】:In a matrix for a given index, how do I check if any neighboring values are 2 smaller than it?在给定索引的矩阵中,如何检查是否有任何相邻值比它小 2?
【发布时间】:2023-03-25 21:15:01
【问题描述】:

我正在做一个蟒蛇挑战,这个让我难过。 这是输入矩阵(numpy 格式):

# [[1, 7, 2, 2, 1],
#  [7, 7, 9, 3, 2],
#  [2, 9, 4, 4, 2],
#  [2, 3, 4, 3, 2],
#  [1, 2, 2, 7, 1]]

函数会输出这个矩阵

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

如果任何(上/下/左/右)邻居比自身小 2,则该值将为“真”。我们一直在学习 numpy,但这并不觉得它是一个太多 numpy 的东西)。

我尝试进行简单的 if comparison=true 检查,但我不断遇到超出索引的错误,我找不到任何方法来规避/忽略这些错误。

提前致谢。


这是我迄今为止所尝试的精髓。我在这里简化了任务,只需要水平检查第一行。如果我可以让它工作,我会扩展它以水平检查下一行直到最后,然后我会做同样的事情,但垂直。

import numpy as np

ex=np.array([[7, 2, 3, 4, 3, 4, 7]])

def count_peaks(A):
    
    matrixHeight=A.shape[0]
    matrixWidth=A.shape[1]
    
    peakTable=np.zeros(shape=(matrixHeight,matrixWidth))
    
    
    for i in range(matrixWidth):
        if A[i]-A[i+1]>=2 or A[i]-A[i-1]>=2:
            peakTable[0,i]=1

    return peakTable

...当然输出:

IndexError: index 1 is out of bounds for axis 0 with size 1

因为我试图找到不存在的 A[-1] 的值。

【问题讨论】:

  • 在我看来很像一个 Numpy 的东西。使用数组的位置偏移副本并将原始数组与它们进行比较。
  • 你说得对,我在 OP 中添加了我的工作。
  • 邻居必须正好小两个才算正确?为什么右下角的1是假的?它的邻居都不比它小两个?
  • 如果任何邻居小>=2,则峰值表为“真”。

标签: python numpy matrix


【解决方案1】:

您使用的是 numpy 数组,所以不要循环,使用矢量代码:

import numpy as np

# get shape
x,y = a.shape

# generate row/col of infinites
col = np.full([x, 1], np.inf)
row = np.full([1, y], np.inf)

# shift left/right/up/down
# and compute difference from initial array
left = a - np.c_[col, a[:,:-1]]
right = a - np.c_[a[:,1:], col]
up = a - np.r_[row, a[:-1,:]]
down = a -np.r_[a[1:,:], row]

# get max of each shift and compare to threshold
peak_table = np.maximum.reduce([left,right,up,down])>=2

# NB. if we wanted to use a maximum threshold, we would use
# `np.minimum` instead and initialize the shifts with `-np.inf`

输出:

array([[False,  True, False, False, False],
       [ True, False,  True, False, False],
       [False,  True, False,  True, False],
       [False, False,  True, False, False],
       [False, False, False,  True, False]])

输入:

import numpy as np
a = np.array([[1, 7, 2, 2, 1],
              [7, 7, 9, 3, 2],
              [2, 9, 4, 4, 2],
              [2, 3, 4, 3, 2],
              [1, 2, 2, 7, 1]])

【讨论】:

  • 我收到 TypeError: list indices must be integers or slices, not tuple 当我点击以左变量开头的行时,变量 a 只是数组的 numpy 数组,对吗?
  • @RichardKYu 为了清楚起见,我添加了输入 array (不是列表),请检查这个。我再次检查,它对我来说很好。
  • 这真是太好了。因此,您为每个值在四个方向上移动,然后四个差异中的最大值产生了一个整数数组,我们可以将其转换为峰值表。 “inf”是表示在某个方向上的比较对于某些条目“不算数”的方式,因为当我们在 reduce 中应用 max 函数时,-inf 将始终被忽略?
  • 你得到了一切;)
【解决方案2】:

如果您不介意我不使用 numpy 来获取解决方案,而是在最后转换为 numpy,这是我的尝试:

import numpy as np

def check_neighbors(mdarray,i,j):
    neighbors = (-1, 0), (1, 0), (0, -1), (0, 1)

    for neighbor in neighbors:
        try:
            if mdarray[i][j]-mdarray[i+neighbor[0]][j+neighbor[1]]>=2:
                return True
        except IndexError:
            pass

    return False


mdarray= [[1, 7, 2, 2, 1],
        [7, 7, 9, 3, 2],
        [2, 9, 4, 4, 2],
        [2, 3, 4, 3, 2],
        [1, 2, 2, 7, 1]]

peak_matrix =[]

for i in range(len(mdarray)):
    row = []
    for j in range(len(mdarray[i])):
        #print(check_neighbors(mdarray,i,j))
        row.append(check_neighbors(mdarray,i,j))
    peak_matrix.append(row)


y=np.array([np.array(xi) for xi in peak_matrix])
print(y)

我使用 try-except 块来避免索引超出范围时出错。

注意:我的输出的第 4 行第 3 列(从 1 开始计数)似乎与您的不同。我认为邻居中的 4 和 2 差异应该使这个条目成为真的?

输出:

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

编辑:从bare except 更改为IndexError,正如cmets 中没有建议的那样。在这种情况下,通过和继续并没有什么不同,但是是的。

【讨论】:

  • 哦,这是一个很酷的方法!另外,我不知道你能做什么,除了:继续。这正是我需要让我的代码正常工作的那种 hack。谢谢!
  • @joachimnogra 很高兴我能帮上忙!如果这有助于您解决问题,请务必使用支票将其标记为完成。
  • @joachimnogra 仅供参考,bare except 被认为是坏的。此外,continue 可以替换为pass,因为它会在此之后继续循环,因为它是最后一条语句......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 2013-05-28
  • 2017-04-11
  • 2013-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
相关资源
最近更新 更多