Подтвердить что ты не робот

Индексирование чисел: возвращение остальных

Простой пример индексирования numpy:

In: a = numpy.arange(10)
In: sel_id = numpy.arange(5)
In: a[sel_id]
Out: array([0,1,2,3,4])

Как вернуть остальную часть массива, которая не индексируется sel_id? Я могу подумать:

In: numpy.array([x for x in a if x not in a[id]])
out: array([5,6,7,8,9])

Есть ли более простой способ?

4b9b3361

Ответ 1

Для этого простого случая 1D я бы использовал логическую маску:

a = numpy.arange(10)
include_index = numpy.arange(4)
include_idx = set(include_index)  #Set is more efficient, but doesn't reorder your elements if that is desireable
mask = numpy.array([(i in include_idx) for i in xrange(len(a))])

Теперь вы можете получить свои значения:

included = a[mask]  # array([0, 1, 2, 3])
excluded = a[~mask] # array([4, 5, 6, 7, 8, 9])

Обратите внимание, что a[mask] не обязательно дает то же самое, что и a[include_index], так как порядок include_index имеет значение для вывода в этом сценарии (он должен быть примерно эквивалентен a[sorted(include_index)]). Однако, поскольку порядок ваших исключенных элементов не определен, это должно работать нормально.


ИЗМЕНИТЬ

Лучший способ создать маску:

mask = np.zeros(a.shape,dtype=bool)
mask[include_idx] = True

(благодаря seberg).

Ответ 2

Вы можете сделать это с помощью булевых масок:

a = numpy.arange(10)

mask = np.ones(len(a), dtype=bool) # all elements included/True.
mask[[7,2,8]] = False              # Set unwanted elements to False

print a[mask]
# Gives (removing entries 7, 2 and 8):
[0 1 3 4 5 6 9]

Дополнение (взято из @mgilson). Созданная двоичная маска может использоваться красиво, чтобы вернуть исходные фрагменты с помощью a[~mask], но это все равно, если исходные индексы были отсортированы.


ИЗМЕНИТЬ: Сдвиг вниз, так как я должен был понять, что в это время я рассмотрю багги np.delete (сентябрь 2012 г.).

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

print np.delete(a, [7,2,8])

Ответ 3

Это больше похоже:

a = numpy.array([1, 2, 3, 4, 5, 6, 7, 4])
exclude_index = numpy.arange(5)
include_index = numpy.setdiff1d(numpy.arange(len(a)), exclude_index)
a[include_index]
# array([6, 7, 4])

# Notice this is a little different from
numpy.setdiff1d(a, a[exclude_index])
# array([6, 7]

Ответ 4

Я бы сделал это с булевой маской, но немного по-другому. Это полезно для работы в N-образных размерах, с непрерывными или нет индексами. Использование памяти будет зависеть от того, создается ли представление или копия для маскированного массива, и я не уверен.

import numpy
a = numpy.arange(10)
sel_id = numpy.arange(5)
mask = numpy.ma.make_mask_none(a.shape)
mask[sel_id] = True
answer = numpy.ma.masked_array(a, mask).compressed()
print answer
# [5 6 7 8 9]

Ответ 5

Кроме того, если они смежны, используйте синтаксис [N:], чтобы выбрать остальные. Например, arr [5:] будет выбирать от 5 до последнего элемента в массиве.

Ответ 6

numpy.setdiff1d(a, a[sel_id]) должен сделать трюк. Не знаю, есть ли что-то более аккуратное, чем это.

Ответ 7

Предполагая, что a является 1D-массивом, вы можете просто поместить элементы, которые вы не хотите из списка индексов:

accept = [i for i in range(a.size) if i not in avoid_list]
a[accept]

Вы также можете попытаться использовать что-то вроде

accept = sorted(set(range(a.size)) - set(indices_to_discard))
a[accept]

Идея заключается в использовании причудливой индексации на дополнении к набору индексов, которые вы не хотите.