2016-01-21 3 views
-1

Каков самый быстрый способ удаления элементов из массива numpy, возвращая их исходные позиции. Следующий код не возвращает все элементы, которые он должен:Удаление элементов из массива numpy с помощью итерации

list = [] 
for pos,i in enumerate(ARRAY): 
    if i < some_condition: 
     list.append(pos) #This is where the loop fails 

for _ in list: 
    ARRAY = np.delete(ARRAY, _) 
+0

не удается, потому что 'p' должно быть' pos' –

+0

извините, опечатка здесь, теперь написано correctcltly – KeVal

+0

Почему вы так уверены, что линия - это где ваша ошибка? – user2357112

ответ

2

По-настоящему кажется, что вы идете об этом неэффективно. Вероятно, вы должны использовать больше встроенных функций numpy - например, np.where, или булевское индексирование. Использование np.delete в цикле, как, что собирается убить любой прирост производительности вы получите от использования NumPy ...

Например (с булевой индексацией):

keep = np.ones(ARRAY.shape, dtype=bool) 
for pos, val in enumerate(ARRAY): 
    if val < some_condition: 
     keep[pos] = False 
ARRAY = ARRAY[keep] 

Конечно, это могло бы быть упрощено (и обобщенно) еще дальше:

ARRAY = ARRAY[ARRAY >= some_condition] 

EDIT

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

mask = ARRAY >= some_condition 
ARRAY = ARRAY[mask] 
OTHER_ARRAY = OTHER_ARRAY[mask] 
... 

Кроме того (и, возможно, это причина, исходный код не работает), как только вы удалите первый индекс из массива в вашем цикле все остальные элементы сдвигают один индекс влево, поэтому вы фактически не удаляете те же элементы, которые вы «помечены» на начальном проходе.

В качестве примера, предположим, что ваш исходный массив был [a, b, c, d, e] и на оригинальном проходе, вы помечено на индексы [0, 2] для удаления (a, c) элементов ... На первом проходе через петлю удаления, вы бы удалить элемент с индексом 0 - Какой бы ваш массив:

[b, c, d, e] 

теперь на второй итерации вашего удаления цикла, вы собираетесь удалить элемент с индексом 2 в новом массиве:

[b, c, e] 

Но посмотрите, вместо удаления c, как мы и хотели, мы фактически удалили d! О, хвати!

Чтобы исправить это, вы, вероятно, могли бы написать свой цикл за reversed(list), но это все равно не приведет к быстрой работе.

+0

Я думал об использовании цикла while, но он не вернет позиции жестоких элементов. И мне нужны позиции, потому что некоторые другие массивы также должны иметь элементы в этих определенных местах (поэтому график можно построить позже). – KeVal

+0

@KeVal - Это не проблема. Просто держите ручку на маске и используйте ее для других массивов. (см. мое редактирование). – mgilson

2

Вам не нужно выполнять итерацию, особенно с простым состоянием.И вам не нужно использовать delete:

Образец массива:

In [693]: x=np.arange(10) 

маска, логический массив был условие истинно (или ложно):

In [694]: msk = x%2==0 
In [695]: msk 
Out[695]: array([ True, False, True, False, True, False, True, False, True, False], dtype=bool) 

where (или nonzero) преобразует его в индексах

In [696]: ind=np.where(msk) 
In [697]: ind 
Out[697]: (array([0, 2, 4, 6, 8], dtype=int32),) 

Вы можете использовать весь ind в одном вызове delete (нет необходимости перебирать):

In [698]: np.delete(x,ind) 
Out[698]: array([1, 3, 5, 7, 9]) 

Вы можете использовать его ind, чтобы сохранить эти значения вместо:

In [699]: x[ind] 
Out[699]: array([0, 2, 4, 6, 8]) 

Или вы можете использовали булево msk непосредственно:

In [700]: x[msk] 
Out[700]: array([0, 2, 4, 6, 8]) 

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

In [701]: x[~msk] 
Out[701]: array([1, 3, 5, 7, 9]) 

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

Смежные вопросы