简体   繁体   English

Python Numpy。 如果该元素位于一对指定元素之间,则删除二维数组中的一个(或多个元素)

[英]Python Numpy. Delete an element (or elements) in a 2D array if said element is located between a pair of specified elements

I have a 2D NumPy array exclusively filled with 1s and 0s.我有一个 2D NumPy 阵列,专门用 1 和 0 填充。

a = [[0 0 0 0 1 0 0 0 1]
     [1 1 1 1 1 1 1 1 1]
     [1 1 1 1 1 1 1 1 1]
     [1 1 1 1 0 0 0 0 1]
     [1 1 1 1 1 1 1 1 1]
     [1 1 1 0 1 1 1 1 1]
     [1 1 1 1 1 1 0 0 1]
     [1 1 1 1 1 1 1 1 1]]

To get the location of the 0s I used the following code:为了获取 0 的位置,我使用了以下代码:

new_array = np.transpose(np.nonzero(a==0))

As expected, I get the following result showing the location of the 0s within the array正如预期的那样,我得到以下结果,显示了数组中 0 的位置

new_array = [[0 0]
             [0 1]
             [0 2]
             [0 3]
             [0 5]
             [0 6]
             [0 7]
             [3 4]
             [3 5]
             [3 6]
             [3 7]
             [5 3]
             [6 6]
             [6 7]]

Now comes my question: Is there way to get the location of the 0s at the start and end of and horizontal group if said group is larger than 2?现在我的问题来了:如果所说的组大于 2,有没有办法在水平组的开始和结束处获取 0 的位置?

EDIT: If group were to finish at the end of a row and continue on the one below it, it would count as 2 separate groups.编辑:如果组要在一行的末尾完成并继续在它下面的一个,它将计为 2 个单独的组。

My first thought was to implement a process that would delete 0s if they are located in-between 0s but I was not able to figure out how to do that.我的第一个想法是实现一个过程,如果它们位于 0 之间,将删除 0,但我无法弄清楚如何做到这一点。

I would like "new_array" output to be:我希望“new_array” output 是:

new_array = [[0 0]
             [0 3]
             [0 5]
             [0 7]
             [3 4]
             [3 7]
             [5 3]
             [6 6]
             [6 7]]

Thanks beforehand!!先谢谢了!!

One possible solution that is easier to follow is:一种更容易遵循的可能解决方案是:

b = np.diff(a, prepend=1)  # prepend a column of 1s and detect
                           # jumps between adjacent columns (left to right)
y, x = np.where(b > 0)  # find positions of the jumps 0->1 (left to right)
# shift positive jumps to the left by 1 position while filling gaps with 0:
b[y, x - 1] = 1
b[y, x] = 0
new_array = list(zip(*np.where(b)))

Another one is:另一个是:

new_array = list(zip(*np.where(np.diff(a, n=2, prepend=1, append=1) > 0)))

Both solutions are based on the np.diff that computes differences between consecutive columns (when axis=-1 for 2D arrays).两种解决方案都基于np.diff计算连续列之间的差异(当axis=-1用于 2D 数组时)。

A flaw in the other solution is that it reports all sequences of zeroes, regardless of their length.另一种解决方案的一个缺陷是它报告了所有的零序列,无论它们的长度如何。 Your expected output also contains such groups, composed of 1 or 2 zeroes, but in my opinion it shouldn't.您预期的 output 也包含此类组,由 1 个或 2 个零组成,但我认为它不应该。

My solution is free of the above flaw.我的解决方案没有上述缺陷。

An elegant tool to process groups of adjacent equal elements is itertools.groupby , so start from:处理相邻相等元素组的优雅工具是itertools.groupby ,所以从:

import itertools

Then generate your intended result as:然后将您的预期结果生成为:

res = []
for rowIdx, row in enumerate(a):
    colIdx = 0  # Start column index
    for k, grp in itertools.groupby(row):
        vals = list(grp)        # Values in the group
        lgth = len(vals)        # Length of the group
        colIdx2 = colIdx + lgth - 1  # End column index
        if k == 0 and lgth > 2: # Record this group
            res.append([rowIdx, colIdx])
            res.append([rowIdx, colIdx2])
        colIdx = colIdx2 + 1    # Advance column index
result = np.array(res)

The result, for your source data, is:对于您的源数据,结果是:

array([[0, 0],
       [0, 3],
       [0, 5],
       [0, 7],
       [3, 4],
       [3, 7]])

As you can see, it doesn't include shorter sequences of zeroes in row 5 and 6.如您所见,它不包括第 5 行和第 6 行中较短的零序列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM