arrays - 如何在数组(numpy)中制作“可变”数字?
问题描述
我正在尝试创建一个数组,其中多次包含相同的数字,但如果我在任何地方更改它,它应该在任何地方都更改。与列表一样:
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”。那么有没有办法对一个数字进行多次引用?我知道你可以用 11 替换所有的 10,但首先这效率太低,其次这可能会搞砸,因为另一个数字也可能巧合为 10。
谢谢。
解决方案
零维 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)
这有点难看,所以下面我将在打印之前转换为浮点数:
>>> 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
最后一点:这比理智的编程更狡猾,所以请把它看作是可以做的,而不是应该做的。
推荐阅读
- r - 使用 POSIXct 在 R 中合并数据帧
- docker - 运行后台进程与在后台运行管道
- html - ASP.NET Core - CSS 背景属性
- java - Firebase - 当存储给某些用户的新数据在数据库中有特定数据时发送通知
- apache-spark - 无法解析给定输入列的“列名”:Spark-SQL
- python - 使用〜否定真假的意外结果
- javascript - 无法处置/销毁 WebRTC RTCPeerConnection
- django - 如何在模型中添加字段
- reactjs - 如何删除上传列表以显示在 antd Upload 中?
- reactjs - 图像选择器 - 使用 Hook 保存 uri