寻找二维阵列中的最佳位置
我正在使用行数和列数相同大小的 2D numpy 数组。我想找到最佳位置,其中每边 2n + 1 将导致最大可能的总和。 2(n) + 1 这里表示相邻元素。
所以二维数组:
[[0 0 0 0 0]
[0 1 1 1 0]
[0 1 1 1 0]
[0 1 1 1 0]
[0 0 0 0 0]]
在这个数组中, (2, 2) 处的元素似乎是 2(1) + 1 处的最佳位置。 因此,在 n = 2
时,理想位置是相同的。但是,在 n = 3
时,它将是 none
,因为这将超出 2D 数组 maces。
这是我解决问题的方法,但没有给出所需的输出。
def find_target_location(arr, area):
sum_1 = 0
sum_2 = sum_1
square_area = (2 * area) + 1
if square_area > len(arr):
return None
for row in range(len(arr)):
for index in range(len(arr[row])):
area_forward = arr[row: square_area + row, index: square_area + index]
# This is where I am doing wrong but cannot figure out.
area_previous = arr[row - len(arr): -row -1, row - len(arr), -index -1]
sum_area_forward = sum(sum(area_forward))
sum_area_backward = sum(sum(area_backward))
sum_2 = sum_area_forward + sum_area_backward
if sum_2 > sum_1:
sum_1 = sum_2
optimal_location = (row, index)
return optimal_location
I'm working with 2D numpy arrays of equal size in terms of the number of rows and columns. I would like to find the optimal location where 2n + 1 on each side would result in highest possible sum. 2(n) + 1 here means the the neghbouring elements.
So the 2D array:
[[0 0 0 0 0]
[0 1 1 1 0]
[0 1 1 1 0]
[0 1 1 1 0]
[0 0 0 0 0]]
In this array, the element at (2, 2) appears to be the optimal location at 2(1) + 1.
So, at, n = 2
the ideal location would be same. However, at n = 3
, it would be none
, because that would exceed the 2D array matices.
This is my approach to the problem, which is not giving the desired output.
def find_target_location(arr, area):
sum_1 = 0
sum_2 = sum_1
square_area = (2 * area) + 1
if square_area > len(arr):
return None
for row in range(len(arr)):
for index in range(len(arr[row])):
area_forward = arr[row: square_area + row, index: square_area + index]
# This is where I am doing wrong but cannot figure out.
area_previous = arr[row - len(arr): -row -1, row - len(arr), -index -1]
sum_area_forward = sum(sum(area_forward))
sum_area_backward = sum(sum(area_backward))
sum_2 = sum_area_forward + sum_area_backward
if sum_2 > sum_1:
sum_1 = sum_2
optimal_location = (row, index)
return optimal_location
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
直接邻居的总和
如果您正在查找具有最大直接相邻邻居值总和的元素的索引:
但请注意,此解决方案在计算其相邻值的总和时会计算元素本身的值。
2n+1
方形邻域中的邻居之和因此,您想对
2n+1
“半径”邻域中的所有邻居求和:我只是对此进行了测试,但是我认为应该有效。请注意,此处将选择最大值的第一个索引,因此,如果您有多个“最佳”位置,那么您将始终以出现的“第一个”位置结束(当从左上角到下角搜索时)正确的)。
我不认为填充是绝对必要的,但它确实可以让您避免进行一些繁琐的算术,并且如果您想在求和相邻值时不计算每个单元格的值,那么它也会有所帮助,例如所以:
如何在没有
stride_tricks
的情况下做到这一点 归根结底,
np.lib.stride_tricks.sliding_window_view
只是聪明的索引。令
x
为这个(5, 5)
数组:假设
n = 1
,因此您所在社区的面积为2n+ 1 = 3。现在想象一下在
x
上放置一个(3, 3)
“窗口”,将窗口的左上角与x< 的左上角匹配/代码>。该“窗口”围绕着这些值。
这些值的列索引是什么?它们是
(0, 1, 2)
。现在,如果我们在
x
上滑动(3, 3)
窗口,我们无法移动该窗口使其悬挂在x 的任何一侧
。因此,我们可以将此窗口移动到x
顶部的最右边,使得窗口的左上角位于索引 2 处。这样,窗口的右上角就会出现与x
的右上角对齐。该窗口现在围绕着这些值的列索引是什么?它们是
(2,3,4)
。让我们创建一个元组列表,它可以代表我们在
x
顶部滑动时选择的列:输出:
Since
x< /code> 是方形的,当我们想要将窗口向下滑动一行时,这些列索引也适用于行(想象一下在
x
上滑动窗口,就像阅读书页一样用英文写——从左到右,从上到下)。如果您采用
idxs
的笛卡尔积,这将为您提供所有 9 个窗口的行索引和列索引:现在,最后一件事:对于
(rows, cols)
的每个元组code>,我们需要再次使用笛卡尔积来获取每个(3, 3)
窗口的所有 9 个索引对。例如,(3, 3)
窗口的 9 个索引锚定在我们开始的x
的左上角,使用这些元组索引到
x< /code>:
现在我们可以将上面的内容包装在另外两个嵌套列表推导式中,以迭代
(rows, cols)
元组:这会产生
(3, 3, 3, 3)< /code> 数组结束然后您可以将最后两个轴相加。
但这种理解是糟糕。幸运的是,
np.ix_()
函数可以非常轻松地以适合 高级索引:现在获取我们的窗口要容易得多(连同设置数据):
这会产生与上面相同的结果。从那里,您可以将总和应用于最后两个轴(每个单独的二维数组的行和列)。
当然,这仍然是一个看起来很糟糕的理解......并且 np.lib.stride_tricks.sliding_window_view 抽象掉了所有索引废话。
Sum of immediate neighbors
If you're looking for the index of the element with the largest sum of immediately adjacent neighbor values:
Note however that this solution counts the value of an element itself when calculating the sum of its neighboring values.
Sum of neighbors in
2n+1
square neighborhoodSo you want to sum all neighbors in a
2n+1
"radius" neighborhood:I've only sort of tested this, but I think it should work. Note here that the first index of the max value will be chosen, so if you have more than one "optimal" location, you'll always end up with the "first" one that occurs (when searching from top-left to bottom-right).
I don't think padding is strictly necessary but it does let you avoid having to do some tedious arithmetic, and also helps if you want to not count the value of each cell when summing the neighboring values, like so:
How to do it without
stride_tricks
At the end of the day,
np.lib.stride_tricks.sliding_window_view
is just clever indexing.Let
x
be this(5, 5)
array:And suppose
n = 1
, so the area of your neighborhood is2n+1 = 3
. Now imagine placing a(3, 3)
"window" overx
, matching the top-left corner of the window with the top-left corner ofx
. That "window" is surrounding the valuesWhat are the column indices of those values? They are
(0, 1, 2)
.Now, if we're sliding a
(3, 3)
window acrossx
, we can't move the window such that it hangs over any side ofx
. So the furthest right we could move this window across the top ofx
would be such that the top-left corner of the window is at index 2. That way, the top-right corner of the window lines up with the top-right corner ofx
. That window is now surrounding the valuesWhat are the column indices of those values? They are
(2, 3, 4)
.Let's create a list of tuples which can represent the columns selected as we slide across the top of
x
:Output:
Since
x
is square, these column indexes will also work for the rows for when we want to slide the window down one row (imagine sliding the window acrossx
the same way you read a page of a book written in English -- left to right, top to bottom).If you take the Cartesian product of
idxs
, this will give you the row and column indices of all 9 windows:Now, one last thing: for each tuple of
(rows, cols)
, we need to take the Cartesian product again to get all 9 index pairs for each(3, 3)
window. For instance, the 9 indices of the(3, 3)
window anchored at the top left ofx
where we start areUsing those tuples to index into
x
:Now we could wrap the above in another two nested list comprehensions to iterate over the
(rows, cols)
tuples:This produces the
(3, 3, 3, 3)
array over which you can then sum the last two axes.But that comprehension is awful. Fortunately, the
np.ix_()
function makes it incredibly easy to get these Cartesian products in a form suitable for advanced indexing:Now getting our windows is much easier (together with the setup data):
Which produces the same result as above. From there, you can apply the sum over the last two axes (the rows and columns of each individual 2D array).
Of course, that's still an awful looking comprehension... and
np.lib.stride_tricks.sliding_window_view
abstracts away all that indexing nonsense.