简体   繁体   English

2d数组的每列的第一个和最后一个数字1的索引

[英]Index of the first and last numbers 1 of each column of an 2d array

I have a 2d array ( Q ) consisting of only zeros and ones (binary matrix). 我有一个2d数组( Q )只包含0和1(二进制矩阵)。 For each column of Q I want to find the index of the first and last row which the value 1 occurs. 对于Q每一列,我想找到值1出现的第一行和最后一行的索引。 Each column contains at least one 1 . 每列至少包含一个1

Here's an example: 这是一个例子:

[[1, 1, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 0, 0, 0],
 [1, 0, 0, 0, 1, 0, 1],
 [0, 0, 0, 1, 0, 1, 1],
 [1, 0, 1, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 1],
 [0, 0, 0, 1, 0, 1, 0]]

boundsList = {0: (0, 4), 1: (0, 1), 2: (0, 5), 3: (1, 6), 4: (2, 2), 5: (3, 6), 6: (2, 5)}

I implemented an algorithm, it works, but for large arrays it is not efficient: 我实现了一个算法,它可以工作,但对于大型数组,它效率不高:

boundsList = {}
for i in range (0, len(Q)):
    column = Q[:,i]
    indexesList = []
    for idx, pos in enumerate (column):
        if pos == 1:
            indexesList.append(idx)
    boundsList[i] = (indexesList[0], indexesList[-1])

Can anybody could suggest another simple solution to this problem? 任何人都可以建议另一个简单的解决方案吗?

Let's start with your array: 让我们从你的数组开始:

>>> Q
array([[1, 1, 1, 0, 0, 0, 0],
       [0, 1, 1, 1, 0, 0, 0],
       [1, 0, 0, 0, 1, 0, 1],
       [0, 0, 0, 1, 0, 1, 1],
       [1, 0, 1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 1],
       [0, 0, 0, 1, 0, 1, 0]])

To obtain the indices for each column of the first row which contains 1: 要获取包含1的第一行的每列的索引:

>>> np.argmax(Q, axis=0) # Index of first appearance of 1
array([0, 0, 0, 1, 2, 3, 2])

To obtain the indices for each column of the last row which contains 1: 要获取包含1的最后一行的每列的索引:

>>> Q.shape[0] - np.argmax(Q[::-1, :], axis=0) - 1 # Index of last appearance of 1
array([4, 1, 5, 6, 2, 6, 5])

To combine them into a dictionary of your liking: 要将它们组合成您喜欢的字典:

>>> dict(enumerate(zip( np.argmax(Q, axis=0), Q.shape[0] - np.argmax(Q[::-1, :], axis=0) - 1)))
{0: (0, 4), 1: (0, 1), 2: (0, 5), 3: (1, 6), 4: (2, 2), 5: (3, 6), 6: (2, 5)}

Probably the fastest way would be to use the argmax method (it works because it finds the position of the first maximum) from both sides and then put that in a dictionary. 可能最快的方法是使用argmax方法(它可以工作,因为它从两侧找到第一个最大值的位置),然后将其放入字典中。 The argmax method has far less overhead (constant factor) than using np.argmax so, especially for small arrays, the method will be much faster. 与使用np.argmax相比, argmax方法具有更少的开销(常数因子),因此,特别是对于小型数组,该方法将更快。

Because dict , enumerate and zip are faster on lists than arrays I also convert the intermediate arrays to lists (the tolist method is the fastest way to achieve that): 因为dictenumeratezip在列表上比数组更快我也将中间数组转换为列表( tolist方法是实现它的最快方法):

>>> dict(enumerate(zip(Q.argmax(axis=0).tolist(), 
...                    (Q.shape[0]-1-Q[::-1].argmax(axis=0)).tolist())))
{0: (0, 4), 1: (0, 1), 2: (0, 5), 3: (1, 6), 4: (2, 2), 5: (3, 6), 6: (2, 5)}

The Q[::-1] is the reversed array and to get the "not-reversed" indices I have to subtract them from Q.shape[0]-1 . Q[::-1]是反向数组,为了得到“未反转”的索引,我必须从Q.shape[0]-1减去它们。

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

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