使用numpy,当a
和b > a
具有不同的长度时,如何获取a
中元素b
的最后一个索引。
例如,对于以下值:
>>> a = np.asarray([10, 20, 30, 40])
>>> b = np.asarray([12, 25])
我期望结果为[0, 1]
(0 ..因为12 > 10
-> a
中的索引0; 1 ..因为25 > 20
-> { {1}})。显然,结果向量的长度应等于a
的长度(并且结果列表的值应小于b
的长度(因为它们引用{{1}中的索引}))。
另一项测试是针对a
(与上述a
相同),结果应为b = np.asarray([12, 25, 31, 9, 99])
。
答案 0 :(得分:3)
矢量化解决方案:
请记住,您可以使用广播将b
中的所有元素与a
中的所有元素进行比较:
b[:, None] > a
# array([[ True, False, False, False], # b[0] > a[:]
# [ True, True, False, False]]) # b[1] > a[:]
现在找到每行中最后一个True
值的索引,该值等于每行中第一个False
值的负1
np.argmin((b[:, None] > a), axis=1) - 1
# array([0, 1])
请注意,返回值-1
的含义可能不明确。可能是
b[x]
比a
中的所有元素大,或者b[x]
不大于a
在我们的数据中,这意味着
a = np.asarray([10, 20, 30, 40])
b = np.asarray([9, 12, 25, 39, 40, 41, 50])
mask = b[:, None] > a
# array([[False, False, False, False], # 9 is smaller than a[:], case 2
# [ True, False, False, False],
# [ True, False, False, False],
# [ True, True, True, False],
# [ True, True, True, False],
# [ True, True, True, True], # 41 is larger than a[:], case 1
# [ True, True, True, True]]) # 50 is larger than a[:], case 1
因此,对于情况1,我们需要找到具有所有True
值的行:
is_max = np.all(mask, axis=1)
对于情况2,我们需要找到具有所有False
值的行:
none_found = np.all(~mask, axis=1)
这意味着我们可以使用is_max
查找并用正索引替换所有案例1 -1
的值
mask = b[:, None] > a
is_max = np.all(mask, axis=1)
# array([False, False, False, False, False, True, True])
idx = np.argmin(mask, axis=1) - 1
# array([-1, 0, 0, 2, 2, -1, -1])
idx[is_max] = len(a) - 1
# array([-1, 0, 0, 2, 2, 3, 3])
但是请注意,索引-1
具有含义:就像3
一样,它已经意味着“最后一个元素”。因此,如果要使用idx
进行索引,将-1
保留为无效值标记可能会造成麻烦。
答案 1 :(得分:0)
np.asarray([i for i in range(len(b)) if b[i]>a[i]])
这应该给您答案。长度也不必与a或b相同。
答案 2 :(得分:0)
即使a
的长度比b
的长度短,也可以先选择较短的列表长度,然后检查其元素编号是否较小:
[i for i in range(min(len(a),len(b))) if min(a, b, key=len)[i] > max(a, b, key=len)[i]]
# [0, 1]
答案 3 :(得分:0)
您可以zip
a和b进行组合,然后enumerate
对其索引进行迭代
[i for i,(x,y) in enumerate(zip(a,b)) if y>x]
# [0, 1]