这是创建numpy数组的只读视图的正确方法吗



我想创建一个对NumPy数组的只读引用。这是使b成为对a的只读引用的正确方法吗(a是任何NumPy数组(?

def get_readonly_view(a):
b = a.view()
b.flags.writeable = False
return b

具体来说,我想确保以上内容不会"复制"a的内容?(我试着用np.shares_memory测试这个,它确实返回了True。但我不确定这是否是一个正确的测试。(

此外,我想知道get_readonly_view是否已经在NumPy中实现了?


更新有人建议将数组转换为类属性,使其只读。我认为这不起作用:

import numpy as np
class Foo:
def __init__(self):
self._a = np.arange(15).reshape((3, 5))

@property
def a(self):
return self._a

def bar(self):
print(self._a)

但客户端可以更改_a:的内容

>> baz = Foo()
>> baz.bar()
[[ 0  1  2  3  4]
[ 5  6  7  8  9]
[10 11 12 13 14]]
>> baz.a[1, 2] = 10
>> baz.bar()
[[ 0  1  2  3  4]
[ 5  6 10  8  9]
[10 11 12 13 14]]

而我希望CCD_ 9引发一个异常。

您的方法似乎是创建只读视图的建议方法。

特别地,arr.view()(也可以写为切片arr[:](将创建对arr的引用,而修改writeable标志是使NumPy数组只读的建议方式。

该文档还提供了一些关于writeable属性继承的附加信息:

可以写入数据区域。将其设置为False会锁定数据,使其只读。视图(切片等(在创建时从其基数组继承WRITEABLE,但在基数组保持可写时,可写数组的视图随后可能被锁定。(事实并非如此,因为锁定数组的视图可能不可写。但是,目前,锁定基对象不会锁定任何已经引用它的视图,因此在这种情况下,可以通过以前创建的可写视图更改锁定数组的内容。(试图更改不可写数组会引发RuntimeError异常。

只是重申并检查正在发生的事情:

import numpy as np

def get_readonly_view(arr):
result = arr.view()
result.flags.writeable = False
return result

a = np.zeros((2, 2))
b = get_readonly_view(a)
print(a.flags)
#   C_CONTIGUOUS : True
#   F_CONTIGUOUS : False
#   OWNDATA : True
#   WRITEABLE : True
#   ALIGNED : True
#   WRITEBACKIFCOPY : False
#   UPDATEIFCOPY : False
print(b.flags)
#   C_CONTIGUOUS : True
#   F_CONTIGUOUS : False
#   OWNDATA : False
#   WRITEABLE : False
#   ALIGNED : True
#   WRITEBACKIFCOPY : False
#   UPDATEIFCOPY : False
print(a.base)
# None
print(b.base)
# [[0. 0.]
#  [0. 0.]]
a[1, 1] = 1.0
# ...works
b[0, 0] = 1.0
# raises  ValueError: assignment destination is read-only

最新更新