Эффективное зацикливание с использованием индексного массива

Если у меня есть индексный массив со всеми уникальными последовательными значениями, такими как:

index_array = array([0, 4, 2, 5, 6, 1, 3, 7, 8])

с соответствующим массивом значений:

value_array = array([0, 400, 200, 500 600, 100, 300, 700, 800])

Можно ли пройти через индексный массив в последовательном порядке, так что я получаю

array([0, 100, 200, 300, 400, 500, 600, 700, 800])

Мне нужно перебрать индексный массив в порядке (т. Е. 0, 1, 2, 3, 4...) с соответствующими значениями (т. Е. 0, 100, 200, 300, 400). Причина, по которой эти значения не в порядке, заключается в том, что я делю ребра, что означает, что новые ребра добавляются в конец массива индекса (используя vstack), а не вставляются в массив индекса в соответствующей точке.

Псевдокод (если бы я печатал значения) был бы примерно таким:

for point in sorted(index_array):

    print sorted(point(value_array))

производство:

0

100

200

300

Насколько это чувствительно к памяти (полагаю, мне нужно было бы использовать numpy.where). Лучше всего переупорядочивать перед циклом, или это приводит к снижению производительности из-за выхода из строя?

1 ответ

Решение

Подход № 1

Получить argsort для массива индекса и индекса в массиве значений -

value_array[index_array.argsort()]

Пробный прогон -

In [129]: value_array
Out[129]: array([   0,  400,  200,  500,  600,  100,  300,  700, 800])

In [130]: index_array
Out[130]: array([0, 4, 2, 5, 6, 1, 3, 7, 8])

In [131]: value_array[index_array.argsort()]
Out[131]: array([   0,  100,  200,  300,  400,  500,  600,  700, 800])

Подход № 2 Злоупотребление тем, что все элементы в index_array уникальны и последовательны, гораздо быстрее будет инициализировать выходной массив и использовать эти индексы для индексации и присвоения этих значений из value_array в это, как так -

def assign_unique_seq(value_array, index_array):
    out = np.empty_like(value_array)
    out[index_array] = value_array
    return out

Тест выполнения -

In [152]: value_array = np.random.randint(0,1000000,(100000))

# Create unique and sequential indices array
In [153]: index_array = np.random.permutation(len(value_array))

In [154]: %timeit value_array[index_array.argsort()]
100 loops, best of 3: 7.84 ms per loop

In [155]: %timeit assign_unique_seq(value_array, index_array)
1000 loops, best of 3: 240 µs per loop
Другие вопросы по тегам