假设我有像
这样的numpy数组x = np.arange(10)
以某种方式可以创建对单个元素的引用,即
y = create_a_reference_to(x[3])
y = 100
print x
[ 0 1 2 100 4 5 6 7 8 9]
答案 0 :(得分:7)
您无法创建对单个元素的引用,但您可以对该单个元素进行查看:
>>> x=numpy.arange(10)
>>> y=a[3:4]
>>> y[0]=100
>>> x
array([0, 1, 2, 100, 4, 5, 6, 7, 8, 9])
你不能做前者的原因是python中的所有内容都是参考。通过执行y = 100
,您可以修改y
指向的内容 - 而不是它的价值。
如果你真的想,你可以get that behaviour on instance attributes by using properties。请注意,这是唯一可能的,因为python数据模型specifies additional operations while accessing class attributes - 它不可能为变量获取此行为。
答案 1 :(得分:2)
不,你不能那样做,那就是按设计。
Numpy数组的类型为numpy.ndarray
。可以使用numpy.ndarray.item
访问其中的单个项目,这样可以将数组的元素复制到标准Python标量并将其返回"。
我猜numpy会返回一个副本,而不是直接引用元素,以防止numpy项目在numpy自己的实现之外的可变性。
正如思想游戏一样,让我们假设情况并非如此,您将被允许参考个别项目。那么如果:numpy处于计算的中间并且你在另一个线程中改变了个人的时间会发生什么呢?
答案 2 :(得分:0)
@goncalopp给出了正确的答案,但有一些变化可以达到类似的效果。
下面显示的所有符号都可以在返回视图时引用单个元素:
x = np.arange(10)
two_index_method = [None] * 10
scalar_element_method = [None] * 10
expansion_method = [None] * 10
for i in range(10):
two_index_method[i] = x[i:i+1]
scalar_element_method[i] = x[..., i] # x[i, ...] works, too
expansion_method[i] = x[:, np.newaxis][i] # np.newaxis == None
two_index_method[5] # Returns a length 1 numpy.ndarray, shape=(1,)
# >>> array([5])
scalar_element_method[5] # Returns a numpy scalar, shape = ()
# >>> array(5)
expansion_method[5] # Returns a length 1 numpy.ndarray, shape=(1,)
# >>> array([5])
x[5] = 42 # Change the value in the original `ndarray`
x
# >>> array([0, 1, 2, 3, 4, 42, 6, 7, 8, 9]) # The element has been updated
# All methods presented here are correspondingly updated:
two_index_method[5], scalar_element_method[5], expansion_method[5]
# >>> (array([42]), array(42), array([42]))
由于scalar_element_method
中的对象是维度零标量,因此尝试通过ndarray
引用element[0]
中包含的元素将返回IndexError
。对于标量ndarray
,element[()]
可用于引用numpy标量中包含的元素。此方法也可用于赋值长度为1 ndarray
,但有一个不幸的副作用,即它不会将长度为1 ndarray
取消引用到python标量。幸运的是,只有一个方法element.item()
可用于(仅用于解除引用)以获取值,无论该元素是长度为ndarray
还是标量为ndarray
:
scalar_element_method[5][0] # This fails
# >>> IndexError: too many indices for array
scalar_element_method[5][()] # This works for scalar `ndarray`s
# >>> 42
scalar_element_method[5][()] = 6
expansion_method[5][0] # This works for length-1 `ndarray`s
# >>> 6
expansion_method[5][()] # Doesn't return a python scalar (or even a numpy scalar)
# >>> array([6])
expansion_method[5][()] = 8 # But can still be used to change the value by reference
scalar_element_method[5].item() # item() works to dereference all methods
# >>> 8
expansion_method[5].item()
# >>> [i]8
TLDR;您可以使用v
,v = x[i:i+1]
或v = x[..., i]
创建单元素视图v = x[:, None][i]
。虽然不同的setter和getter适用于每种方法,但您始终可以使用v[()]=new_value
分配值,并且始终可以使用v.item()
检索python标量。