Как удалить определенные элементы в массиве numpy

Как удалить некоторые элементы из массива numpy? Скажем, у меня

import numpy as np

a = np.array([1,2,3,4,5,6,7,8,9])

Затем я хочу удалить 3,4,7 из a. Все, что я знаю, это индекс значений (index=[2,3,6]).

Ответ 1

Использовать numpy.delete() - возвращает новый массив с субмассивами вдоль удаленной оси

numpy.delete(a, index)

По вашему конкретному вопросу:

import numpy as np

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
index = [2, 3, 6]

new_a = np.delete(a, index)

print(new_a) #Prints `[1, 2, 5, 6, 8, 9]`

Обратите внимание, что numpy.delete() возвращает новый массив, поскольку массивные массивы неизменяемы, подобно строкам в Python, поэтому каждый раз, когда происходит изменение к нему создается новый объект. I.e., чтобы процитировать delete() docs:

"Копия arr с элементами, указанными obj удалены. удаление не происходит на месте..."

Если код, который я публикую, имеет выход, это результат запуска кода.

Ответ 2

Существует встроенная функция numpy, которая поможет с этим.

import numpy as np
>>> a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> b = np.array([3,4,7])
>>> c = np.setdiff1d(a,b)
>>> c
array([1, 2, 5, 6, 8, 9])

Ответ 3

Массив Numpy immutable, что означает, что вы технически не можете удалить элемент из него. Однако вы можете построить новый массив без значений, которые вы не хотите, например:

b = np.delete(a, [2,3,6])

Ответ 4

Чтобы удалить по значению:

modified_array = np.delete(original_array, np.where(original_array == value_to_delete))

Ответ 5

Не будучи бесчисленным человеком, я сделал снимок с помощью:

>>> import numpy as np
>>> import itertools
>>> 
>>> a = np.array([1,2,3,4,5,6,7,8,9])
>>> index=[2,3,6]
>>> a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))
>>> a
array([1, 2, 5, 6, 8, 9])

Согласно моим тестам, это превосходит numpy.delete(). Я не знаю, почему это так, возможно, из-за небольшого размера исходного массива?

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
100000 loops, best of 3: 12.9 usec per loop

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "np.delete(a, index)"
10000 loops, best of 3: 108 usec per loop

Это довольно значительная разница (в противоположность тому, что я ожидал), у кого-нибудь есть идея, почему это будет так?

Еще более странно, переходя numpy.delete(), список работает хуже, чем цикл через список и дает ему одиночные индексы.

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "for i in index:" "    np.delete(a, i)"
10000 loops, best of 3: 33.8 usec per loop

Изменить: похоже, это зависит от размера массива. При больших массивах numpy.delete() выполняется значительно быстрее.

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))"
10 loops, best of 3: 200 msec per loop

python -m timeit -s "import numpy as np" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "np.delete(a, index)"
1000 loops, best of 3: 1.68 msec per loop

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

Ответ 6

Если вы не знаете индекс, вы не можете использовать logical_and

x = 10*np.random.randn(1,100)
low = 5
high = 27
x[0,np.logical_and(x[0,:]>low,x[0,:]<high)]

Ответ 7

Удалить конкретный индекс (я удалил 16 и 21 из матрицы)

import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)

Выход:

array([[12, 13, 14, 15],
      [17, 18, 19, 20],
      [22, 23, 24, 25]])

Ответ 8

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

a = numpy.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
the_index_list = [2, 3, 6]

the_big_set = set(numpy.arange(len(a)))
the_small_set = set(the_index_list)
the_delta_row_list = list(the_big_set - the_small_set)

a = a[the_delta_row_list]