Python 二维数组每列的第一个和最后一个数字的索引1

Python 二维数组每列的第一个和最后一个数字的索引1,python,performance,python-3.x,numpy,multidimensional-array,Python,Performance,Python 3.x,Numpy,Multidimensional Array,我有一个二维数组(Q),它只包含0和1(二进制矩阵)。对于Q的每一列,我想找到值为1的第一行和最后一行的索引。每列至少包含一个1 下面是一个例子: [[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]] boundsL

我有一个二维数组(
Q
),它只包含0和1(二进制矩阵)。对于
Q
的每一列,我想找到值为1的第一行和最后一行的索引。每列至少包含一个
1

下面是一个例子:

[[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)}
我实现了一个算法,它可以工作,但对于大型阵列,它效率不高:

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])

有人能为这个问题提出另一个简单的解决方案吗?

让我们从您的阵列开始:

>>> 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]])
要获取包含1的第一行每列的索引,请执行以下操作:

>>> np.argmax(Q, axis=0) # Index of first appearance of 1
array([0, 0, 0, 1, 2, 3, 2])
>>> Q.shape[0] - np.argmax(Q[::-1, :], axis=0) - 1 # Index of last appearance of 1
array([4, 1, 5, 6, 2, 6, 5])
要获取包含1的最后一行中每列的索引,请执行以下操作:

>>> np.argmax(Q, axis=0) # Index of first appearance of 1
array([0, 0, 0, 1, 2, 3, 2])
>>> Q.shape[0] - np.argmax(Q[::-1, :], axis=0) - 1 # Index of last appearance of 1
array([4, 1, 5, 6, 2, 6, 5])
要将它们合并到您喜欢的词典中:

>>> 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)}

可能最快的方法是从两侧使用该方法(它可以工作,因为它首先找到最大值的位置),然后将其放入字典中。与使用
np相比,
argmax
方法的开销(常数因子)要少得多。argmax
因此,特别是对于小数组,该方法将更快

由于
dict
enumerate
zip
在列表上比数组快,我还将中间数组转换为列表(使用
tolist
方法是实现这一点的最快方法):


Q[::-1]
是反向数组,为了得到“未反向”索引,我必须从
Q.shape[0]-1

中减去它们。每个列都至少有一个
1
?是的,在该列中至少会找到一个值1。数组中只有值0和1。感谢绅士们,所有提出的算法都优雅地解决了这个问题。