我正在尝试制作一个数组,该数组多次包含相同的数字,但是如果我在任何地方更改它,它应该随处更改。像列表一样:
a = b = [1]
>>> a.append(1)
>>> print(b)
>>> [1, 1]
所以我想要一个这样的数组:
number = 10
arr = numpy.zeros((10, 10))
arr[0][0] = number
arr[1][1] = number
arr[0][0] += 1
print(arr[1][1])
此处应输出“ 11”。那么,有没有一种方法可以引用多个数字呢?我知道您可以将所有的10替换为11,但是首先这效率太低,其次,因为另一个数字也可能恰好是10,所以这可能会使事情搞砸。
谢谢。
答案 0 :(得分:1)
零维numpy数组在许多方面的行为就像可变数字:
>>> 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)
这有点难看,所以下面我将在打印之前将其转换为float:
>>> 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
,而不是{{1 }}。
我们可以使用inplace(3
)运算符和一些技巧来获得这种行为;如果我们想保留原始的*=
,则必须首先进行复制:
由于A
的复制机制将我们的0D阵列归一化,因此需要更多的技巧才能制作出优质的副本:
numpy
现在对副本执行就地乘法:
>>> 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
最后的提示:这比合理的编程要复杂得多,因此请认为它是可以完成的,而不是应该完成的。