简体   繁体   English

Python:在几种情况下查找数组的索引

[英]Python: finding index of an array under several conditions

I have the following problem. 我有以下问题。 There are two n-dimensional arrays of integers and I need to determine the index of an item that fulfills several conditions. 有两个整数的n维数组,我需要确定满足多个条件的项目的索引。

  • The index should have a negative element in "array1". 索引应在“ array1”中包含一个负数元素。
  • Of this subset with negative elements, it should have the smallest value in "array2". 在具有负元素的此子集中,它应具有“ array2”中的最小值。
  • In case of a tie, select the value that has the smallest value in "array1" (or the first otherwise) 如果是平局,请选择“ array1”中具有最小值的值(否则,请选择第一个)

So suppose we have: 因此,假设我们有:

array1 = np.array([1,-1,-2])
array2 = np.array([0,1,1])

Then it should return index 2 (the third number). 然后,它应该返回索引2(第三个数字)。 I'm trying to program this as follows: 我正在尝试如下编程:

import numpy as np
n = 3
array1 = np.array([1,-1,-2])
array2 = np.array([0,1,1])
indices = [i for i in range(n) if array1[i]<0] 
indices2 = [i for i in indices if array2[i] == min(array2[indices])] 
index = [i for i in indices2 if array1[i] == min(array1[indices2])][0] #[0] breaks the tie.

This seems to work, however, I don't find it very elegant. 这似乎可行,但是我觉得它不是很优雅。 To me it seems like you should be able to do this in one or two lines and with defining less new variables. 在我看来,您应该可以在一两行中定义较少的新变量来执行此操作。 Anyone got a suggestion for improvement? 有人提出改善建议吗? Thanks in advance. 提前致谢。

you can get the indices of all negative elements from array1 with: 您可以使用以下命令从array1获取所有负元素的索引:

np.where(array1 < 0)

then you can access the subset via: 那么您可以通过以下方式访问该子集:

subset = array2[array1 < 0]

to get the index of the smallest (negative) value of array1, you can use array1.argmin() 要获取array1的最小(负)值的索引,可以使用array1.argmin()

value = array2[array1.argmin()]

putting all together gives you: 放在一起给你:

value = array2[array1 < 0][array1[array1 < 0].argmin()]

but you have to catch ValueErrors, if array1 has only positive values. 但是如果array1仅具有正值,则必须捕获ValueErrors。

I don't know much about numpy (though apparently i should really look into it), so here is a plain python solution 我对numpy不太了解(尽管显然我应该认真研究一下),所以这是一个简单的python解决方案

This 这个

sorted([(y, x, index) for (index, (x, y)) in enumerate(zip(array1, array2)) if x < 0])

will give you the tripley of elements from array2, array1, index sorted by value in array2 and value in array1 in case of tie, index in case of tie 将为您提供来自array2,array1的元素的三元组,如果是平局,则索引按array2中的值和array1中的值排序,如果平局,则索引

The first element is what you seek. 第一个要素是您要寻找的东西。 This gives the following result : 得到以下结果:

[(1, -2, 2), (1, -1, 1)]

The index is therefore 2, and is obtained by [0][2] 因此,索引为2,并由[0][2]

The index should have a negative element in "array1" : 索引在“ array1”中应该有一个负数

indices_1 = np.argwhere(array1 < 0)

Of this subset with negative elements, it should have the smallest value in "array2". 在具有负元素的此子集中,它应具有“ array2”中的最小值。

indices_2 = array2[indices_1].argmin()

In case of a tie, select the value that has the smallest value in "array1" (or the first otherwise) 如果是平局,请选择“ array1”中具有最小值的值(否则,请选择第一个)

array1[indices_2].argmin()

I came up with this. 我想到了这个。 Just devised one more test case and seemed to work. 刚刚又设计了一个测试用例,似乎可以正常工作。 See if it suits your needs. 查看它是否适合您的需求。

sorted([(array2[index], element, index) for index, element in enumerate(array1) if element<0])[0][2]

Or through using the min function. 或通过使用min函数。

min([(array2[index], element, index) for index, element in enumerate(array1) if element<0])[2]

The following will work with numpy arrays of any dimension. 以下将适用于任何尺寸的numpy数组。 It uses numpy.lexsort to order the indices. 它使用numpy.lexsort对索引进行排序。

numpy.lexsort(Y,X) sorts the items in X in ascending order, and breaks ties according to the values in Y. It returns the indices in order (not the values of X or Y .) This is the only function I know of in numpy which "breaks ties" for you. numpy.lexsort(Y,X)按照升序对X中的项目进行排序,并根据Y中的值断开关系。它按顺序返回索引(不是XY的值。)这是我知道的唯一函数在numpy中为您“打破联系”。


import numpy as np
def find_index(array1, array2):
    indices = np.where(array1 < 0)
    i = np.lexsort((array1[indices],array2[indices]))[0]
    return [idx[i] for idx in indices]

array1 = np.array([1,-1,-2])
array2 = np.array([0,1,1])

array3 = np.array([(1, 2),
                   (-1, -2),
                   (-2, 0)])
array4 = np.array([(0, 2),
                   (1, 1),
                   (3, 0)])

print(find_index(array1, array2))
# [2]

print(find_index(array3, array4))
# [1, 1]

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

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