【问题标题】:Find sequence in two Numpy arrays在两个 Numpy 数组中查找序列
【发布时间】:2014-06-21 20:20:49
【问题描述】:

我有两个 Numpy 数组,其中包含来自另一个数组的最大值和最小值的索引。

例如,对于一个输出,最大值和最小值数组如下所示:

Maxima indices are (array([ 4, 10, 14, 37, 43, 51, 59, 67, 81, 89, 95]),)
Minima indices are (array([ 7, 12, 25, 33, 40, 49, 56, 63, 76, 92]),)

这些索引来自图像行中的强度值。

我需要找出一个最大值在两个最小值之间的四个索引位置内出现了多少次 - 换句话说:

minima + 4 + maxima + 4 + minima

如何在 Python 中有效地做到这一点?如何比较两个数组中的索引值以找到该序列的实例,然后计算总共有多少个实例?

非常感谢您的帮助。

编辑:每个最大值必须在左右最接近最小值的 4 个位置内。基本上,我试图根据强度值识别图像中的虚线。

【问题讨论】:

  • 最大值是否必须在左侧和右侧最近最小值的 4 个位置内?还是在一个最小值的 4 个位置内就足够了?
  • 最大值必须在左侧和右侧最近最小值的 4 个位置内 - 是的。我将编辑问题以反映这一点。感谢您的提问。
  • 好的,我的答案中的代码应该考虑到它。它只是使单向遍历变得不可能。

标签: python arrays algorithm numpy sequence


【解决方案1】:

让我们试试吧。

import numpy

# create a vector for distances from the nearest leftmost minimum
# img_len is the length of the image row

# first we create an integer vector with 1 at each minimum
b = numpy.zeros(img_len, dtype='int')

# then we create an integer vector for the distances
d = numpy.zeros(img_len, dtype='int')

# we mark leftmost distances up to the first minimum to be largest possible
d[:minima[0]] = minima[0] - numpy.arange(minima[0])

# then we iterate through the vector and calculate the distances
for i in range(len(minima) - 1):
    prev = minima[i]
    next = minima[i+1]
    # now we have a gap between the two minima
    # let's fill it with a triangle 0,1,2,...,2,1,0
    k = (next-prev + 1) // 2
    d[prev:prev+k+1] = numpy.arange(k+1)
    d[next-k+1:next] = k -1 - numpy.arange(k-1)

# fill in the space after the last minimum:
d[minima[-1]:] = numpy.arange(img_len - minima[-1])

# all maxima whose distance is less than D from the closest minimum
results = [ m for m in maxima if d[m] < D ]

除非代码很明显,否则我们的想法是创建一个向量d,它对应于与最近最小值的距离。结果向量是,例如,4,3,2,1,0,1,2,3,2,1,0,1,2,1,0,... 其中零对应于最小位置。最困难的事情是让循环中的三角形制作正确。 (我希望我把所有的都清理干净了……)

当然,现在你也可以为最大值位置创建一个元组列表:

[ (m, d[m]) for m in maxima ]

对于问题中的数据,返回:

[(4, 3),
 (10, 2),
 (14, 2),
 (37, 3),
 (43, 3),
 (51, 2),
 (59, 3),
 (67, 4),
 (81, 5),
 (89, 3),
 (95, 3)]

即使问题中的两个最小值之间存在多个最大值,该代码也可以工作。 (如果只有一个最大值,那么代码几乎完全不同。)

【讨论】:

  • 感谢您的详细回复。我收到代码错误:d[:minima[0]] = minima[0] - np.arange(minima[0]) - 只有长度为 1 的数组可以转换为 Python 标量。最小值数组是 minima = argrelextrema(img_row, np.less) 的输出,其中 img_row 是相关图像水平线的像素强度值的 Numpy 数组。你能帮忙吗?
  • 如果你问type(minima[0]),你的python会说什么?它对type(minima)minima.shapelen(minima) 说了什么?
  • type(minima[0]) = type(minima) = minima.shape = AttributeError: 'tuple' object has no attribute 'shape ' len(最小值) = 1
  • 是的。试试:minima = argrelexrema(img_row, np.less)[0](和类似的 [0] 表示最大值)。这是因为argrelextrema 返回一个输出列表。来自argrelextrema 的文档:“请注意,即使数据是一维的,返回值也是一个元组。”
  • 试过了。现在我得到一个错误 - results = [ m for m in maxima if d[m]
【解决方案2】:

我会将此作为另一个答案,因为这是一种完全不同的方法。不是很节省空间,但代码很短,而且很麻木。

import numpy

# let's assume minima and maxima are 1-d arrays
# then the distance matrix for distances between any maximum to any minimum is:
md = numpy.amin(numpy.abs(maxima[:,None]-minima[None,:]), axis=1)

# the maxima which are at most D pixels away form the closest minima:
cm = maxima[md < D]

这些当然可以组合成一个很难理解的单行。

简要说明:

  • 计算所有最小值(列)和最大值(行)之间的距离矩阵(充满冗余和不相关的信息)
  • 矩阵的绝对值给出了每个最大值到每个最小值之间的距离
  • 使用amin 操作沿行获取从每个最大值到任何最小值的最短距离
  • cm 是通过使用布尔数组索引最大值来计算的(距离低于限制的为真)

如果向量很长,这可能会变慢。不着急的话,这是一段简单的代码。

【讨论】:

    猜你喜欢
    • 2015-05-31
    • 2017-12-23
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多