简体   繁体   中英

How to find closest elements in two array without repetitions [duplicated] and return the indexs of two array in Python?

I have 2 arrays list1 and list2

list1= np.array([0.        , 0.09705882, 0.19411765, 0.29117647, 0.38823529,
       0.48529412, 0.58235294, 0.67941176, 0.77647059, 0.87352941,
       0.97058824, 1.06764706, 1.16470588, 1.26176471, 1.35882353,
       1.45588235, 1.55294118, 1.65      , 1.74705882, 1.84411765,
       1.94117647, 2.03823529, 2.13529412, 2.23235294, 2.32941176,
       2.42647059, 2.52352941, 2.62058824, 2.71764706, 2.81470588,
       2.91176471, 3.00882353, 3.10588235, 3.20294118, 3.3       ,
       3.39705882, 3.49411765, 3.59117647, 3.68823529, 3.78529412,
       3.88235294, 3.97941176, 4.07647059, 4.17352941, 4.27058824,
       4.36764706, 4.46470588, 4.56176471, 4.65882353, 4.75588235,
       4.85294118, 4.95      , 5.04705882, 5.14411765, 5.24117647,
       5.33823529, 5.43529412, 5.53235294, 5.62941176, 5.72647059,
       5.82352941, 5.92058824, 6.01764706, 6.11470588, 6.21176471,
       6.30882353, 6.40588235, 6.50294118, 6.6       ])
list2=np.array([3.3 , 3.2 , 3.1 , 3.  , 2.9 , 2.8 , 2.7 , 2.6 , 2.5 , 2.4 , 2.3 ,
       2.2 , 2.1 , 2.  , 1.9 , 1.8 , 1.7 , 1.6 , 1.5 , 1.4 , 1.3 , 1.2 ,
       1.1 , 1.05, 0.95, 0.85, 0.75, 0.7 , 0.6 , 0.5 , 0.4 , 0.3 , 0.2 ,
       0.1 , 0])


for each element in a I would like to find the closest element in b and return the index of both of them

list2aux = list(list2)
mylist = []
for idxlabel in range(0,len(list1)): 
    a = min(enumerate(list2aux), key=lambda x:abs(x[1]-list1[idxlabel]))
    list2aux[a[0]] = 0
    print(a)
    mylist.append(np.copy(a))

My problem is that after that one element in list2 is found as "best match" I would like to print the index of both elements in arrays whose values are close together also I would like to remove it from the search to avoid that different element in list1 match with the same element in list2

(34, 0.0)
(33, 0.1)
(32, 0.2)
(31, 0.3)
(30, 0.4)
(29, 0.5)
(28, 0.6)
(27, 0.7)
(26, 0.75)
(25, 0.85)
(24, 0.95)
(23, 1.05)
(21, 1.2)
(20, 1.3)
(19, 1.4)
(18, 1.5)
(17, 1.6)
(16, 1.7)
(15, 1.8)
(14, 1.9)
(13, 2.0)
(12, 2.1)
(11, 2.2)
(10, 2.3)
(9, 2.4)
(8, 2.5)
(7, 2.6)
(6, 2.7)
(5, 2.8)
(4, 2.9)
(3, 3.0)
(2, 3.1)
(1, 3.2)
(0, 3.3)
(22, 1.1)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)
(0, 0)

in this example Zero value is repeated !!! And the index of one of the array is displayed if I need the index of both elements in arrays whose values are close together

You can use numpy.where() to get indexes of matched elements in numpy arrays.

Given the two lists above, you can try this following code (without removing elements from list2 after found):


for i in range(len(list1)):

  temp_result = abs(list1[i] - list2) #Matrix subtraction

  min_val = np.amin(temp_result) #Getting the minimum value to get closest element
  min_val_index = np.where(temp_result == min_val) #To find index of minimum value

  closest_element = list2[min_val_index] #Actual value of closest element in list2

  print(i, list1[i], min_val_index[0][0], closest_element[0])


Removing elements as soon as they are found in list2, eventually, list2 will be empty so to avoid any runtime errors the safety check is present.

for i in range(len(list1)):

  if (len(list2)) > 1: #When there are elements in list2

    temp_result = abs(list1[i] - list2) #Matrix subtraction

    min_val = np.amin(temp_result) #Getting the minimum value to get closest element
    min_val_index = np.where(temp_result == min_val) #To find index of minimum value

    closest_element = list2[min_val_index] #Actual value of closest element in list2

    list2 = list2[list2 != closest_element] #Remove closest element after found

    print(i, list1[i], min_val_index[0][0], closest_element[0]) #List1 Index, Element to find, List2 Index, Closest Element

  else: #All elements are already found

    print(i, list1[i], 'No further closest unique closest elements found in list2')

You don't need to use enumerate() here. Instead, you can iterate over list1 and find the closest element of list2 using a simpler min() call.

In order to prevent duplicate matches in list2 , you can remove each element from list2 as you find it. Numpy arrays are immutable, which makes this a little more complex. Here's an example assuming ordinary python lists, allowing you to use the standard remove() method.

# iterate by value
for list1_val in list1:
  # stop when list2 is empty
  if len(list2) == 0:
      break
  # find the closest match
  list2_val = min(list2, key=lambda x:abs(x-list1_val))
  # print the value pair
  print(list1_val, ',', list2_val)
  # remove the match from list2
  list2.remove(list2_val)

This yields the result:

0.0 , 0
0.09705882 , 0.1
0.19411765 , 0.2
0.29117647 , 0.3
0.38823529 , 0.4
0.48529412 , 0.5
0.58235294 , 0.6
0.67941176 , 0.7
0.77647059 , 0.75
0.87352941 , 0.85
0.97058824 , 0.95
1.06764706 , 1.05
1.16470588 , 1.2
1.26176471 , 1.3
1.35882353 , 1.4
1.45588235 , 1.5
1.55294118 , 1.6
1.65 , 1.7
1.74705882 , 1.8
1.84411765 , 1.9
1.94117647 , 2.0
2.03823529 , 2.1
2.13529412 , 2.2
2.23235294 , 2.3
2.32941176 , 2.4
2.42647059 , 2.5
2.52352941 , 2.6
2.62058824 , 2.7
2.71764706 , 2.8
2.81470588 , 2.9
2.91176471 , 3.0
3.00882353 , 3.1
3.10588235 , 3.2
3.20294118 , 3.3
3.3 , 1.1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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