Замініть від’ємні значення в масиві numpy


90

Чи існує простий спосіб замінити всі від’ємні значення в масиві на 0?

У мене є повний блок, як це зробити за допомогою масиву NumPy.

Напр

a = array([1, 2, 3, -4, 5])

Мені потрібно повернутися

[1, 2, 3, 0, 5]

a < 0 дає:

[False, False, False, True, False]

Тут я застряг - як використовувати цей масив для модифікації вихідного масиву.

Відповіді:


137

Ви на півдорозі. Спробуйте:

In [4]: a[a < 0] = 0

In [5]: a
Out[5]: array([1, 2, 3, 0, 5])

89

Спробуйте numpy.clip:

>>> import numpy
>>> a = numpy.arange(-10, 10)
>>> a
array([-10,  -9,  -8,  -7,  -6,  -5,  -4,  -3,  -2,  -1,   0,   1,   2,
         3,   4,   5,   6,   7,   8,   9])
>>> a.clip(0, 10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Ви можете закріпити лише нижню половину clip(0).

>>> a = numpy.array([1, 2, 3, -4, 5])
>>> a.clip(0)
array([1, 2, 3, 0, 5])

Ви можете відрізати лише верхню половину clip(max=n). (Це набагато краще, ніж моя попередня пропозиція, яка передбачала перехід NaNдо першого параметра та використання outдля примусу типу.):

>>> a.clip(max=2)
array([ 1,  2,  2, -4,  2])

Ще одним цікавим підходом є використання where:

>>> numpy.where(a <= 2, a, 2)
array([ 1,  2,  2, -4,  2])

Нарешті, розглянемо відповідь Екса . Я віддаю перевагу clipпростим операціям, оскільки це самодокументування, але його відповідь переважніша для більш складних операцій.


1
a.clip (0) було б достатньо, оскільки OP просто хоче замінити негативні значення. a.clip (0, 10) виключає все, що перевищує 10.
Усагі

1
@Hiett - я щойно спробував, і кліп візьме один. Спочатку приймається хв.
Усагі

повинна бути проблема з версією numpy - ось мій вихід: (Pdb) np.clip (w, 0) *** TypeError: clip () приймає принаймні 3 аргументи (2 задані) - тоді як: (Pdb) np.clip ( w, 0,1e6) масив ([[0., 0.605]])
bph

1
@Hiett, до якої версії numpy? Чи пробували ви кліп метод з a? Вбудована функція numpy.clipвидає мені таку ж помилку, але метод - ні.
senderle

так, якщо ви так це називаєте, здається, це працює, наприклад, масив p w.clip (0) ([[[0., 0.605]]) - як queer?
bph

10

Ще одне мінімалістичне рішення Python без використання numpy:

[0 if i < 0 else i for i in a]

Не потрібно визначати додаткові функції.

a = [1, 2, 3, -4, -5.23, 6]
[0 if i < 0 else i for i in a]

врожайність:

[1, 2, 3, 0, 0, 6]

1
це приємно - мені було цікаво, яким би був синтаксис для розміщення оператора if у розумінні списку - я помилився, приклеївши його після циклу for і лише потім повернувши два значення, наприклад [0, 0] для вашого прикладу список
bph

Я зробив те саме, коли спочатку дізнався про розуміння списку і випробовував різні речі, щоб перевірити своє розуміння - здавалося більш інтуїтивним поставити це після циклу for і для мене. Тепер це робить :) Поміщення його перед застосуванням forзастосовується до кожного елемента списку, а після - означає, лише якщо умова виконана, воно потрапляє до отриманого списку.
Левон,

2
@Hiett Це просто використання тернарного оператора ( i < 0 ? 0 : iв С) всередині розуміння списку. Вставте дужки, щоб було зрозуміліше [(0 if i < 0 else i) for i in a]. Постановка if після використовує фільтрувальну частину конструкції виразу списку. [(i) for i in a if i < 0]поверне лише список елементів, які менше нуля.
Paul S

2
Numpy є потужним, оскільки робить багато обчислень за скомпільованим кодом і, отже, швидше. Порівнюючи цей метод з іншими, я виявляю майже в 10 разів коефіцієнт коефіцієнта швидкості (це повільніше). Отже, хоча це інтуїтивно зрозуміло і легко читається, це точно не для обчислювальних процесів.
rspencer


2

Ось спосіб зробити це в Python без NumPy. Створіть функцію, яка повертає те, що ви хочете, і використовуйте розуміння списку або функцію карти .

>>> a = [1, 2, 3, -4, 5]

>>> def zero_if_negative(x):
...   if x < 0:
...     return 0
...   return x
...

>>> [zero_if_negative(x) for x in a]
[1, 2, 3, 0, 5]

>>> map(zero_if_negative, a)
[1, 2, 3, 0, 5]

1
пішов цим маршрутом, але думав, що це повинен бути простіший, більше MATLAB менше python спосіб зробити це за допомогою numpy (оскільки я все одно використовував масиви, а не списки). кліп ідеальний
bph
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.