获取一行中最小值的索引,结合其他限制条件

3

我需要在一个二维数组中找到每行最小值的索引,同时满足列值的附加约束条件。有两个数组ab

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])

b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])

本文旨在寻找符合以下条件的索引:a == 1b为正数且是该行中最小的b值。满足前两个条件很容易实现。

idx = np.where(np.logical_and(a == 1, b > 0))

这将产生以下索引:

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

现在我需要过滤掉重复的行条目(仅保留最小值),但我想不到一个优雅的方法来实现。在上面的例子中,结果应该是:
(array([0,1,3]), array([0,2,0]))

编辑:

它还应该适用于包含除了01之外的其他值的a


1
你能[编辑]以包含你想要的输出吗? - Jon Clements
@JonClements 我添加了预期的输出。 - Christian K.
可能是我自己的问题,但我不明白为什么在示例输出中0出现了两次而1被省略了。 - Jon Clements
使用a上的条件,您可以获得两个维度的索引。在b中检查这些位置是否与每行最小的非负值相符。如果不匹配,则删除它。 - Christian K.
2个回答

2

更新以更好地理解问题,尝试:

c = b*(b*a > 0)
np.where(c==np.min(c[np.nonzero(c)]))

输出:

(array([0, 1, 3], dtype=int64), array([0, 2, 0], dtype=int64))

时间:

方法1

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])
b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])
b[b<0] = 100000
cond = [[True if i == b.argmin(axis=1)[k] else False for i in range(b.shape[1])] for k in range(b.shape[0])]
idx = np.where(np.logical_and(np.logical_and(a == 1, b > 0),cond))
idx

方法2

c = b*(b*a > 0)
idx1 = np.where(c==np.min(c[np.nonzero(c)]))
idx1

方法1时间:

每次循环28.3微秒±418纳秒(平均值±7次运行的标准偏差,每次循环10000次)

方法2时间:

每次循环12.2微秒±144纳秒(平均值±7次运行的标准偏差,每次循环100000次)


1
我不确定我是否理解这与我的问题有什么关系。 - Christian K.
方法2的一个缺点是当min()的参数是一个空数组时,它会抛出一个异常。 - Christian K.

0

我找到了一个基于列表推导的解决方案。虽然需要将 b 的负值更改为一些较高的值。

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])
b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])
b[b<0] = 100000
cond = [[True if i == b.argmin(axis=1)[k] else False for i in range(b.shape[1])] for k in range(b.shape[0])]
idx = np.where(np.logical_and(np.logical_and(a == 1, b > 0),cond))
print(idx)

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

请告诉我你的想法。
编辑:我刚刚注意到这个解决方案非常慢。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接