наглое назначение с маскировкой - PullRequest
0 голосов
/ 09 февраля 2019

Я новичок в Python.Во время упражнения я должен использовать маску для умножения всех значений ниже 100 в следующем списке на 2:

a = np.array([230, 10, 284, 39, 76])

Итак, я написал следующий код:

import numpy as np
a = np.array([230, 10, 284, 39, 76])
cut = 100
a[a < cut] = a*2    

Это приводитв следующей ошибке:
IndexError: индекс 230 выходит за пределы для оси 0 с размером 5

Это сбивает с толку, поскольку, насколько я понимаю, a в [a < cut] фактически ссылается на каждое значение вмассив a, но a в a*2 относится ко всему массиву.

Как я могу исправить этот код, используя метод маскирования, вместо использования цикла?

Ответы [ 4 ]

0 голосов
/ 09 февраля 2019

В качестве альтернативы, после определения маски вы можете использовать numpy.where или numpy.putmask

import numpy as np

a = np.array([230, 10, 284, 39, 76])
cut = 100
mask = a < cut # defines the mask

Первое не меняет оригиналмассив:

res = np.where(mask, a*2,a)
a #=> [230  10 284  39  76]
res #=> [230  20 284  78 152]

Второй изменяет исходный массив:

np.putmask(a, mask, a*2)
a #=> [230  20 284  78 152]
0 голосов
/ 09 февраля 2019

Не совсем точно, что вы хотите, если вы хотите назначить места, где хранится a < cut (a < cut = [0, 1, 0, 1, 1] - логический индекс), когда вы присваиваете a[a < cut], вы назначаете места, где элемент равен 1Это означает, что с правой стороны он ожидает массив размером 3 (или, конечно, одно число).Вы можете сделать это

In [1]: a = np.array([230, 10, 284, 39, 76])

In [2]: a[a < cut] = 999

In [3]: a
Out[3]: array([230, 999, 284, 999, 999])

Или

In [1]: a = np.array([230, 10, 284, 39, 76])

In [2]: a[a < cut] = a[a < cut] * 2

In [3]: a
Out[3]: array([230,  20, 284,  78, 152])

Чтобы умножить выбранные элементы на 2.

0 голосов
/ 09 февраля 2019

Ваша ошибка выглядит так: a[a] не a[a<cut]:

In [508]: a[a]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-508-bcb5f2cb8e92> in <module>()
----> 1 a[a]

IndexError: index 230 is out of bounds for axis 1 with size 5

Но для просмотра назначенного задания:

In [497]: a = np.array([230, 10, 284, 39, 76])
In [498]: mask = a<100
In [499]: mask
Out[499]: array([False,  True, False,  True,  True])

Так что mask выбирает3 из 5 элементов a:

In [500]: a[mask]
Out[500]: array([10, 39, 76])

a*2 умножает все элементы a, создавая массив из 5 элементов

In [501]: a*2
Out[501]: array([460,  20, 568,  78, 152])

, соответствующий двум, связанполучить какую-то ошибку;Я получаю:

In [502]: a[mask] = a*2
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-502-3df3d7d2d307> in <module>()
----> 1 a[mask] = a*2

ValueError: NumPy boolean array indexing assignment cannot assign 5 input values to the 3 output values where the mask is true

Но если я наложу маску и на правую сторону:

In [503]: a[mask] = a[mask]*2
In [504]: a
Out[504]: array([230,  20, 284,  78, 152])

Но * = сделает умножение на месте еще проще.

In [506]: a[mask] *= 2
0 голосов
/ 09 февраля 2019

Почти все правильно;

a[a < cut] *= 2

Он выполнит операцию на месте, вы умножаете целый массив a на два и пытаетесь "вписать его" в пространство a

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