Удаление объекта Numpy из списка Python - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть список (x, y) координат:

[[120.027954 167.9987  ]
 [918.95233  175.37206 ]
 [918.14026  540.6017  ]
 [113.1368   535.2902  ]] 

Я хочу удалить по одной строке за раз:

centers = list(centers)

top_left = min(centers, key=sum)
print("top_left ", top_left)
centers.remove(top_left)

bottom_right = max(centers, key=sum)
print("bottom_right ", bottom_right)
centers.remove(bottom_right)

В последней строке выше яполучить эту ошибку:

('top_left ', array([120.027954, 167.9987  ], dtype=float32))
('bottom_right ', array([918.14026, 540.6017 ], dtype=float32))    
centers.remove(bottom_right) 
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()

Я не знаю, почему работает central.remove (top_left), но не работает central.remove (bottom_right)?

1 Ответ

0 голосов
/ 28 сентября 2018

Функция удаления Python оптимизирована для первой проверки на идентичность, а затем для проверки на равенство.Таким образом, для alist.remove(item) сначала проверяется item is alist[0] (проверка идентичности, ищется место в памяти), а затем проверяется item == alist[0] (проверка равенства, просматривается фактическое значение (я))

Однако для массивов с нулевыми значениямиравенство переопределяется с помощью numpy для возврата проверки каждого элемента.(Векторизованная проверка. np.array([1, 2]) == np.array([2, 2]) возвращает np.array([False, True]).) Это не может быть обработано функцией удаления, потому что она ожидает только один логический тип.

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

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

ind = min(range(len(centers)), key=lambda ind: sum(centers[ind]))

Для других людей лучше написать собственную функцию с циклом, проверяющим равенство самостоятельно, вместо того, чтобы по умолчанию использовать функцию равенства numpy.

РЕДАКТИРОВАТЬ:

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

summed_centers = centers.sum(axis=1)
mask = np.ones(len(summed_centers), np.bool_)
mask[[summed_centers.argmax(), summed_centers.argmin()]] = np.bool_(False)
new_centers = centers[mask]

EDIT2:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...