У меня есть два массива разных размеров, и я хочу определить, где элементы одного массива можно найти в другом массиве. Я хотел бы иметь возможность учитывать допуск между элементами. Цель будет примерно такой:
array1 = [1, 2, 3, 4, 5, 6]
array2 = [2, 8, 1.00001, 1.1]
places = [mystery function](array1, array2, tolerance = 0.001)
возвращение индексов places = [0,1]
в array1
.
Самое близкое, что я могу получить, это np.isin
, который позволяет использовать массивы разных размеров и порядков, но не допуск. (тоже пробовали np.allclose
, но здесь проблема с несоответствием формы и порядка). Конечно, это можно сделать с помощью цикла, но мои фактические массивы состоят из тысяч элементов, поэтому цикл нецелесообразен.
(это также не обязательно должна быть пустая функция - на самом деле это просто что-то более эффективное, чем цикл)
Заранее спасибо за помощь!
Используйте searchsorted, затем сравните разницу
Хотя я конкретно не знаю функции в numpy, я только что написал ее.
Надеюсь это поможет:
import numpy as np
def find_indices_within_tolerance(array1, array2, tolerance):
results = []
for i, a1_elem in enumerate(array1):
for a2_elem in array2:
if abs(a1_elem - a2_elem) <= tolerance:
results.append(i)
results = list(set(results))
results.sort()
return results
array1 = np.array([1, 2, 3, 4, 5, 6])
array2 = np.array([2, 8, 1.00001, 1.1])
places = find_indices_within_tolerance(array1, array2, tolerance=0.001)
print(places)
-> yields: [0, 1]
Привет! Большое спасибо за ответ! Это очень полезно, но можно ли сделать это без сортировки массива1? В моих данных отсортированный массив1 отличается от несортированного, и важно, чтобы я получил индексы «мест» для несортированного массива.
@celery, пожалуйста, проверьте, делает ли это то, что вам нужно сейчас. Этот процесс немного медленнее, так как функционально он представляет собой умножение матриц для сравнения элементов.
С помощью пользовательской функции для поиска абсолютной разницы между двумя массивами и позициями, которые соответствуют заданному допуску:
array1 = np.array([1, 2, 3, 4, 5, 6])
array2 = np.array([2, 8, 1.00001, 1.1])
tolerance = 0.001
def argwhere_close(a, b, tol):
return np.where(np.any(np.abs(a - b[:, None]) <= tolerance, axis=0))[0]
print(argwhere_close(array1, array2, tolerance))
[0 1]
Значит, это несоответствие формы и размеров вас так пугает, что вы даже не можете его детализировать? С этим зависанием вы не сможете избежать циклов numpy.
isin
избегает этого, поскольку сводит задачу к 1d, в которой затем можно использовать сортировку.