Есть ли более элегантный способ получения значений по показателям в двумерном массиве? - PullRequest
0 голосов
/ 31 января 2019

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

РЕДАКТИРОВАТЬ: баллы - это матрица 500х10, у - список из 500 знаков от 0 до 9. Мне нужно выбрать 500 значений, соответствующих у.

# scores: 2D matrix  
# y: array of indices

dummy_array = range(scores.shape[0])  
scores[range(dummy_array), y]

Ответы [ 2 ]

0 голосов
/ 31 января 2019

В связанном вопросе:

Как индексировать ndarray другим ndarray?

a = np.arange(50).reshape(10, 5) # Array to be indexed
b = np.arange(9, -1, -2) # Indexing array

Выбор одного элемента из каждого столбца выполняется с помощью:

In [252]: a[b, np.arange(5)]
Out[252]: array([45, 36, 27, 18,  9])

Аналогичное действие в MATLAB требует, Как выбрать один элемент из каждого столбца матрицы в Matlab? , sub2ind функция, которая unravels индексы, создавая плоскостьlist:

a(sub2ind(size(a), b, 1:length(b)))

numpy имеет аналогичную функцию - построение индексов для 1d сглаживания (или выравнивания) буфера данных:

In [253]: np.ravel_multi_index((b, np.arange(5)), a.shape)
Out[253]: array([45, 36, 27, 18,  9])
In [254]: a.flat[_]
Out[254]: array([45, 36, 27, 18,  9])

Эти Out[253] числа рассчитываются по формуле:

In [256]: b*5 + np.arange(5)
Out[256]: array([45, 36, 27, 18,  9])

Таким образом, независимо от того, предоставляем ли мы np.arange(5), или просто 5, или оно выводится из a.shape, значения необходимы для получения плоских индексов.Сокрытие этого шага не сэкономит вам ни времени, ни памяти.

Обратите внимание, что порядок этих значений не является регулярным, поэтому его нельзя выразить в виде среза.В более общем случае мы просто выбираем точки, разбросанные случайным образом вокруг массива a.Их не должно быть по одному на строку (или столбец), их может быть несколько или их нет.

Здесь простота в глазах смотрящего.Для меня идея индексирования с помощью

a[x, y]

, где x и y могут быть любыми массивами, которые можно транслировать, проста.

0 голосов
/ 31 января 2019

Вы можете использовать понимание списка:

l = [j[y[i]] for i, j in enumerate(scores)]

l - это ваш список длиной 500 *. 1005 *

Но также numpy.arange(), как сказано в комментариях.

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