在2d布尔数组(Python)中查找最顶层真值索引的有效方法

2024-10-01 15:44:31 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个形状为(nrows,ncols)的二维布尔数组。我试图为数组中的每一列有效地提取最顶层真值的索引。如果该列具有所有False值,则不会为该列返回任何索引。下面是一个具有形状(4,6)的布尔数组示例,其中粗体Trues的索引将是所需的输出

假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假假

TrueFalseTrueFalse

真假假假

真假真假假

指数(行、列)的期望输出:[(1,0)、(2,2)、(1,3)、(2,5)]

我尝试使用numpy.where和skyline算法的一个实现,但这两个选项都很慢。有没有更有效的方法来解决这个问题

提前感谢您的帮助


Tags: numpyfalse示例数组指数where形状顶层
3条回答

如果您愿意使用pandas,您可以构造一个df,只删除带有False的列,然后idxmax

arr = [[False, False, False, False, False, False],
       [True, False, False, True, False, False],
       [True, False, True, False, False, True],
       [True, False, True, True, False, False]]

df = pd.DataFrame(arr, columns=range(len(arr[0])))

s = df.loc[:, df.sum()>0].idxmax()
print (s)

结果:

0    1
2    2
3    1
5    2
dtype: int64

这是列值对行值。您可以将其转换回所需的格式:

print (list(zip(s, s.index)))

[(1, 0), (2, 2), (1, 3), (2, 5)]

您可以使用^{}来检测第一个True

准备示例数组

import numpy as np
a = np.array(
[[0,0,0,0,0,0],
 [1,0,0,1,0,0],
 [1,0,1,0,0,1],
 [1,0,1,1,0,0]]).astype('bool')
a

输出

array([[False, False, False, False, False, False],
       [ True, False, False,  True, False, False],
       [ True, False,  True, False, False,  True],
       [ True, False,  True,  True, False, False]])

堆叠一行False以处理没有True的列。用np.argmax查找每列中的第一个True,并为行索引追加一个arange。您必须按-1调整列索引,因为我们向数组中添加了一行。然后选择True的索引大于0的列

b = np.vstack([np.zeros_like(a[0]),a])
t = b.argmax(axis=0)
np.vstack([t - 1, np.arange(len(a[0]))]).T[t > 0]

输出

array([[1, 0],
       [2, 2],
       [1, 3],
       [2, 5]])

@HenryYik答案转换为numpy给出了一行解决方案

np.vstack([a.argmax(axis=0), np.arange(len(a[0]))]).T[a.sum(0) > 0]

输出

array([[1, 0],
       [2, 2],
       [1, 3],
       [2, 5]])

我建议你试试这个:

def get_topmost(ar: np.ndarray):
    return [(row.index(True), i) for i, row in enumerate(ar.T.tolist()) if True in row]

示例:(应按原样工作)

>>> test = np.array([
    [False, False, False, False, False, False],
    [True,  False, False, True,  False, False],
    [True,  False, True,  False, False, True],
    [True,  False, True,  True,  False, False],
])

>>> print(get_topmost(test))
[(1, 0), (2, 2), (1, 3), (2, 5)]

相关问题 更多 >

    热门问题