Нольмерный массив numy во многих отношениях ведет себя как изменяемое число:
>>> import numpy as np
>>>
>>> a = 2.0 # ordinary immutable number
>>> am = np.array(2.0) # "mutable number"
>>>
>>> A = np.array([[a, a, am, a], [am, am, a, a]], dtype=object)
>>> A
array([[2.0, 2.0, array(2.), 2.0],
[array(2.), array(2.), 2.0, 2.0]], dtype=object)
Это немного некрасиво, поэтому ниже я преобразую в число с плавающей точкой перед печатью:
>>> A.astype(float)
array([[2., 2., 2., 2.],
[2., 2., 2., 2.]])
Эти двое не все равны, верхний левый является неизменным
>>> A[0, 0] += 1
Это влияет на назначение только непосредственно адресуемой ячейки:
>>> A.astype(float)
array([[3., 2., 2., 2.],
[2., 2., 2., 2.]])
>>> a
2.0
Третий два является изменяемым
>>> A[0, 2] -= 1
Назначение для него затрагивает все ссылки:
>>> A.astype(float)
array([[3., 2., 1., 2.],
[1., 1., 2., 2.]])
>>> am
array(1.)
Прямое назначение требует [()]
синтаксис:
>>> A[0, 2][()] = 1.5
>>> am
array(1.5)
В противном случае ссылка будет разорвана:
>>> A[0, 2] = 1.8
>>> A.astype(float)
array([[3. , 2. , 1.8, 2. ],
[1.5, 1.5, 2. , 2. ]])
Обновление:
В комментарии OP указывается следующее желаемое поведение:
Если изменяемое число am
встречается k
раз в A
, то в A * 3
изменяемое число должно быть умножено на 3**k
, а не 3
.
Мы можем получить это поведение, используя оператор inplace (*=
) и некоторые хитрости;Если мы хотим сохранить оригинал A
, мы должны сначала сделать копию:
Поскольку копирующее устройство numpy
s нормализует наши 0D-массивы, для создания хорошей копии требуется еще несколько хитростей:
>>> import copy
>>>
>>> B = np.empty_like(A)
>>> B.ravel()[...] = copy.deepcopy((*A.ravel(),))
Теперь выполните умножение на месте для копии:
>>> import operator as op
>>>
>>> C = np.frompyfunc(op.imul, 2, 1)(B, 3)
>>>
>>> A
array([[2.0, 2.0, array(2.), 2.0],
[array(2.), array(2.), 2.0, 2.0]], dtype=object)
>>> C
array([[6.0, 6.0, array(54.), 6.0],
[array(54.), array(54.), 6.0, 6.0]], dtype=object)
Обратите внимание, что B
будет содержать некоторые бесполезные гибридные данные в конце и их следует отбросить.
>>> B
array([[2.0, 2.0, array(54.), 2.0],
[array(54.), array(54.), 2.0, 2.0]], dtype=object)
>>> del B
Последнее замечание: это более хитрое, чем нормальное программирование, поэтому, пожалуйста, расценивайте его как «можно сделать», а не как следует ».