2015-06-22 2 views
2
A = np.array([[1,2,3],[3,4,5],[5,6,7]]) 
X = np.array([[0, 1, 0]]) 
for i in xrange(np.shape(X)[0]): 
    for j in xrange(np.shape(X)[1]): 
     if X[i,j] == 0.0: 
      A = np.delete(A, (j), axis=0) 

Я пытаюсь удалить j из A если в X есть 0 в индексе j. Я получаюPython np.delete вопрос

IndexError: index 2 is out of bounds for axis 0 with size 2. 

, если X является [[0,1,0]] то A должен стать [[3,4,5]].

ответ

3

Не звоните np.delete в петлю. Было бы быстрее использовать булеву индексацию:

In [6]: A[X.astype(bool).any(axis=0)] 
Out[6]: array([[3, 4, 5]]) 

X.astype(bool) превращает 0 в False и любое ненулевое значение в True:

In [9]: X.astype(bool).any(axis=0) 
Out[9]: array([False, True, False], dtype=bool) 

вызов к .any(axis=0) возвращается True если любое значение в столбец X.astype(bool) - True, и False в противном случае.


Удаление элементов из списка (или массива), а цикл по тому же списку a classic pitfall. Проблема заключается в том, что факт, что удаление элементов из списка изменяет значение индексации , так что если вы используете порядковое индексирование для удаления других элементов, вы можете завершить до удаления неправильных элементов или получить IndexError, если попытаетесь индекс за пределами допустимого диапазона для измененного списка.

В вашем случае, когда вы цикл через ряды А, а также удалять строки матрицы А:

for j in xrange(np.shape(X)[1]): 
    if X[i,j] == 0.0: 
     A = np.delete(A, j, axis=0) 

каждый раз, когда вы изменяете A индекса в A изменений. Так

 A = np.delete(A, 0, axis=0) 

удаляет первую строку исходной A, но теперь новый A имеет только две строки. Так

 A = np.delete(A, 2, axis=0) 

поднимает IndexError, так как 2 относится к третьему ряду, и новый А не имеет третий ряд. Эта проблема только усугубляется, если i -loop вызывает так называемое многократное появление A = np.delete(A, j, axis=0).