Python 单个numpy数组元素的引用

Python 单个numpy数组元素的引用,python,numpy,Python,Numpy,假设我有一个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] 您不能创建对单个元素的引用,但可以在该元素上获得视图: >>> x = numpy.arange(10) >>> y = x[3:4] >>> y[0]

假设我有一个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]

您不能创建对单个元素的引用,但可以在该元素上获得视图

>>> x = numpy.arange(10)
>>> y = x[3:4]
>>> y[0] = 100
>>> x
array([0, 1, 2, 100, 4, 5, 6, 7, 8, 9])
不能使用前者的原因是python中的所有内容都是引用。通过执行
y=100
,您正在修改
y
指向的内容,而不是它的值


如果你真的想,你可以。注意,这只可能是因为python数据模型-不可能获得变量的这种行为。

不,您不能这样做,这是设计的

Numpy数组的类型为
Numpy.ndarray
。可以使用
numpy.ndarray.item
访问其中的单个项,它会“将数组的元素复制到标准Python标量并返回”

我猜numpy会返回一个副本,而不是直接引用元素,以防止numpy项在numpy自己的实现之外的可变性


作为一个想法,让我们假设情况并非如此,您将被允许获得对单个项目的引用。那么,如果:numpy处于计算中期,而你在另一个线程中改变了一个个体的时间,会发生什么呢?

@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\u element\u方法
中的对象是零维标量,因此尝试通过
element[0]
引用
ndarray
中包含的元素将返回一个
索引器
。对于标量
ndarray
元素[()]
可用于引用numpy标量中包含的元素。此方法也可用于分配给length-1
ndarray
,但不幸的是,它没有将length-1
ndarray
解引用到python标量。幸运的是,有一个方法,
element.item()
,可用于(仅用于取消引用)获取值,而不管元素是长度为1的
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=x[i:i+1]
v=x[…,i]
v=x[:,None][i]
创建单个元素视图
v
。虽然每个方法都使用不同的setter和getter,但您始终可以使用
v[()]=new_value
分配值,并且始终可以使用
v.item()

检索python标量。您确定这一点吗?例如,可以创建一个数组视图,即y=x[4:6](参见上面的答案)。如果我操作这个视图,我也会对原始数组进行更改。@jrsm jsalonen的观点是,你不能回避numpy。使用一个视图,您会发现。是否可以将我的变量封装在一个类中以获得这种行为?