Создание образца 2d массива:
In [51]: data = np.random.randint(0,3,(3,4))
In [52]: data
Out[52]:
array([[2, 0, 1, 2],
[1, 1, 0, 2],
[1, 1, 1, 2]])
логическая маска ненулевых элементов:
In [53]: data>0
Out[53]:
array([[ True, False, True, True],
[ True, True, False, True],
[ True, True, True, True]])
где / ненулевые индексы этих элементов:
In [54]: idx = np.nonzero(data>0)
In [55]: idx
Out[55]: (array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2]), array([0, 2, 3, 0, 1, 3, 0, 1, 2, 3]))
Этот кортеж может использоваться непосредственно для индекса data
(или любого массива той же формы):
In [56]: data[idx]
Out[56]: array([2, 1, 2, 1, 1, 2, 1, 1, 1, 2])
Это то же самое, что и непосредственное использование логической маски:
In [57]: data[data>0]
Out[57]: array([2, 1, 2, 1, 1, 2, 1, 1, 1, 2])
Эти ненулевые элементы могут быть выбраны и / или изменены
In [58]: data[idx] = data[idx] * 2
In [59]: data
Out[59]:
array([[4, 0, 2, 4],
[2, 2, 0, 4],
[2, 2, 2, 4]])
(Поскольку data
- это целочисленный тип d, я не пытался разделить, что приведет к созданию значений с плавающей запятой.)
ufunc
как у деления, добавления, и т.д. c, есть параметр where
. Например, взять инверсию ненулевых элементов:
In [71]: data = np.random.randint(0,3,(3,4)).astype(float)
In [72]: data
Out[72]:
array([[1., 0., 0., 2.],
[1., 0., 1., 2.],
[0., 2., 2., 1.]])
In [73]: np.divide(1, data, where=data>0, out=data)
Out[73]:
array([[1. , 0. , 0. , 0.5],
[1. , 0. , 1. , 0.5],
[0. , 0.5, 0.5, 1. ]])