Возвращайте номера из списка, которые находятся ближе друг к другу, чем пороговое значение

#python #list #numpy #scipy #element

Вопрос:

Я хотел бы вернуть числа из списка, которые ближе друг к другу, чем порог. Я могу сделать это с помощью этого скрипта, но я ищу более быстрое решение. Возможно ли это с помощью NumPy или SciPy?

 mylist = [2, 4, 54, 43, 43, 3]

for i in range(len(mylist)):
    for j in range(i   1, len(mylist)):
        closer_than = 2
        if mylist[i] < mylist[j]   closer_than and mylist[i] > mylist[j] - closer_than:
            print("close values:", mylist[i], mylist[j])    
 

Комментарии:

1. Может быть, так будет лучше для codereview.stackexchange.com

2. Если вы сначала выполните сортировку, то сможете остановить j цикл, когда значения находятся слишком далеко друг от друга, что сделает это намного быстрее.

Ответ №1:

Вы можете использовать combinations из itertools для создания пар между всеми числами. Затем вы можете отфильтровать эти комбинации по своему пороговому значению.

 from itertools import combinations


mylist = [2, 4, 54, 43, 43, 3]


def get_close_numbers(l, threshold):
    combs = combinations(mylist, 2)
    return list(filter(lambda x: abs(x[0] - x[1]) < threshold, combs))

get_close_numbers(mylist, threshold=2)
>> [(2, 3), (4, 3), (43, 43)]
 

Ответ №2:

Это можно сделать с помощью numpy.

 import numpy as np

mylist = np.array( [2, 4, 54, 43, 43, 3] )
threshold = 2

temp =abs( np.subtract.outer( mylist, mylist ))
# Subtract each item from each item, keeping the absolute value.

temp
# array([[ 0,  2, 52, 41, 41,  1],
#        [ 2,  0, 50, 39, 39,  1],
#        [52, 50,  0, 11, 11, 51],
#        [41, 39, 11,  0,  0, 40],
#        [41, 39, 11,  0,  0, 40],
#        [ 1,  1, 51, 40, 40,  0]])

temp[ np.tril_indices_from(temp) ] = threshold
# Set the lower left triangle to threshold

r_ix, c_ix = np.where( temp < threshold )
# find where temp < threshold

# Use the indices to find the values.
list(zip(mylist[ r_ix], mylist[ c_ix ]))
# [(2, 3), (4, 3), (43, 43)]