удаление строк на основе значения, найденного в указанном столбце - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь написать код, который ищет массив значений для случаев, когда значение в пятом столбце не имеет 50.Если это не так, я хочу удалить его.

Это то, что я имею до сих пор:

for rows in range(len(b)):
    if b[:,4].any() != 50:
        b = np.delete(b, b[rows])

Однако, я продолжаю получать следующую ошибку:

слишком много индексов для массива

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Позволяет запустить расчет с некоторыми диагностическими отпечатками.Обратите внимание, где происходит ошибка.Это важно!(Мы не должны просто продолжать попытки, не изолируя проблему!)

In [2]: b=np.array([[0,1,2],[1,2,3],[2,1,2]])
In [3]: for row in range(len(b)):
   ...:     print(row)
   ...:     if b[:,2].any() !=2:
   ...:         print(b[row])
   ...:         b = np.delete(b, b[row])
   ...:         
0
[0 1 2]
1
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-3-04dc188d9a2b> in <module>()
      1 for row in range(len(b)):
      2     print(row)
----> 3     if b[:,2].any() !=2:
      4         print(b[row])
      5         b = np.delete(b, b[row])
IndexError: too many indices for array

Таким образом, ошибка возникает во 2-й итерации (row 1).Что-то не так с b после удаления.Каково новое значение b?

In [4]: b
Out[4]: array([1, 2, 3, 2, 1, 2])

b - это массив 1d, а не 2d, с которого мы начали.Это объясняет ошибку, верно?Что-то должно быть не так с использованием delete.Может быть, нам нужно проверить его документацию ????

Посмотрите на параметр axis:

axis : int, optional
  The axis along which to delete the subarray defined by `obj`.
  If `axis` is None, `obj` is applied to the flattened array.

Мы не указали ось, поэтому удаление было применено к сглаженномумассив и результат были сглажены - 1d.

Но даже если я укажу ось, я получу ошибку (я не буду вдаваться в это), что побудит меня более внимательно посмотреть на условие if:

In [10]: b[:,2]
Out[10]: array([2, 3, 2])
In [11]: b[:,2].any()
Out[11]: True
In [12]: b[:,2]!=2
Out[12]: array([False,  True, False])

Применение any к столбцу не имеет смысла - он просто проверяет, не равны ли какие-либо значения в столбце 0. Вместо этого мы хотим проверить столбец с целью, получая логическое значение, котороесоответствует размеру столбца.

Мы можем использовать это логическое значение непосредственно как маску выбора строки

In [13]: b[_,:]
Out[13]: array([[1, 2, 3]])

Нет необходимости повторять.

Еще одна проблема с вашей итерацией.Вы выполняете итерацию в диапазоне (3), [0,1,2].Но внутри цикла вы пытаетесь удалить строку из b, изменив размер b.Это создаст проблемы при попытке индексировать b[row] по номеру, верно?При выполнении итераций в Python или numpy будьте осторожны с изменением объекта, для которого вы выполняете итерацию.

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

Вот базовый подход к списку:

In [15]: [row for row in b if row[2]!=2]
Out[15]: [array([1, 2, 3])]

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

0 голосов
/ 16 октября 2018

Было бы лучше предоставить b и желаемый результат, но если я правильно понимаю, вы можете использовать:

import numpy as np

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


array([[50,  2,  3,  4,  5,  6],
       [ 4, 50,  6,  7,  8,  9],
       [ 1,  1,  1,  1, 50,  9]])

Затем вы можете проверить, какие строки содержат 50 в 5-м столбцеиспользуя

b[:, 4] == 50
array([False, False,  True])

и верните этот логический массив обратно к b, чтобы выбрать нужные столбцы:

b[b[:, 4] == 50]

, что оставляет вам одну строку в этом случае

array([[ 1,  1,  1,  1, 50,  9]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...