如何在数组(numpy)中创建一个“可变”数字?

时间:2018-09-20 07:32:46

标签: arrays numpy reference

我正在尝试制作一个数组,该数组多次包含相同的数字,但是如果我在任何地方更改它,它应该随处更改。像列表一样:

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,所以这可能会使事情搞砸。

谢谢。

1 个答案:

答案 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在注释中指定以下所需行为:

如果可变数amk中出现了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

最后的提示:这比合理的编程要复杂得多,因此请认为它是可以完成的,而不是应该完成的。