Как получить массив без пары элементов ближе по расстоянию - PullRequest
1 голос
/ 15 октября 2019

Я хочу удалить элементы из пустого вектора, которые ближе, чем расстояние d. (Я не хочу, чтобы какая-либо пара в массиве или списке имела расстояние между ними меньше, чем d, но не хочу полностью удалять эту пару.

например, если мой массив:

array([[0.       ],
       [0.9486833],
       [1.8973666],
       [2.8460498],
       [0.9486833]], dtype=float32)

Все, что мне нужно, это удалить либо элемент с индексом 1 или 4. Не оба из них.

Мне также нужны индексы элементов из исходного массивакоторые остаются в скрытом.

Так как исходный массив находится в tenorflow 2.0, я буду счастлив, если преобразование в numpy не требуется, как описано выше. Из-за скорости я также предпочитаю не использовать другой пакет и оставаться сnumpy или scipy.

Спасибо.

Ответы [ 3 ]

1 голос
/ 15 октября 2019

с использованием numpy:

import numpy as np

a = np.array([[0.       ],
              [0.9486833],
              [1.8973666],
              [2.8460498],
              [0.9486833]])

threshold = 1.0
# The indices of the items smaller than a certain threshold, but larger than 0.
smaller_than = np.flatnonzero(np.logical_and(a < threshold, a > 0))
# Get the first index smaller than threshold
first_index = smaller_than[0]

# Recreate array without this index (bit cumbersome)
new_array = a[np.arange(len(a)) != first_index]

Я почти уверен, что это действительно легко воссоздать в tensorflow, но я не знаю как.

1 голос
/ 15 октября 2019

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

THRESHOLD = 0.1    
def wrangle(l):
    for i in range(len(l)):
        for j in range(len(l)-1, i, -1):
            if abs(l[i] - l[j]) < THRESHOLD:
                l.pop(j)
0 голосов
/ 16 октября 2019

Если ваш массив действительно только 1-й, вы можете сгладить его и сделать что-то вроде этого:

a=tf.constant(np.array([[0.       ],
                        [0.9486833],
                        [1.8973666],
                        [2.8460498],
                        [0.9486833]], dtype=np.float32))

d = 0.1

flat_a = tf.reshape(a,[-1])  # flatten



a1 = tf.expand_dims(flat_a, 1)
a2 = tf.expand_dims(flat_a, 0)
distance_map = tf.math.abs(a1-a2)
too_small = tf.cast(tf.math.less(dist_map, d), tf.int32)  
# 1 at indices i,j if the distance between elements at i and j is less than d, 0 otherwise

upper_triangular_part = tf.linalg.band_part(too_small, 0, -1) - tf.linalg.band_part(too_small, 0,0)

remove = tf.reduce_sum(upper_triangular_part, axis=0)
remove = tf.cast(tf.math.greater(remove, 0), tf.float32)
# 1. at indices where the element should be removed, 0. otherwise

output = flat_a - remove * flat_a

Вы можете получить доступ к индексам через тензор удаления. Если вам нужно дополнительное измерение, вы можете просто использовать tf.expand_dims в конце этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...