问题
As my MWE below shows, calling np.array(a, copy=False)
on an existing array a
returns something that behaves exactly as expected, except that the .data
attributes seem to differ. How can this be?
>>> a # My original array
array([2])
>>> b = np.array(a, copy=False) # Not-a-copy of the original array
>>> b is a # The Python objects seem to be identical
True
>>> b.data is a.data # But their .data attributes aren't??
False
>>> a.data
<memory at 0x7f82ebd757c8>
>>> b.data
<memory at 0x7f82ebd75888>
>>> b
array([2])
>>> a
array([2])
>>> a[:] = 3 # Changing a indeed also changes b
>>> a
array([3])
>>> b
array([3])
>>> a.data
<memory at 0x7f82ebd757c8>
>>> b.data
<memory at 0x7f82ebd75888>
EDIT
While playing around, I even found that the .data
attribute changes while looking at it!
>>> a.data is a.data # a.data isn't equal to itself?!
False
>>> a.data
<memory at 0x7f82ebd75948>
>>> a.data
<memory at 0x7f82ebd75888> # A different value than a minute ago
>>> a.data
<memory at 0x7f82ebd75948>
>>> a.data
<memory at 0x7f82ebd75888>
>>> a.data
<memory at 0x7f82ebd75948>
>>> a.data
<memory at 0x7f82ebd75888>
>>> a.data
<memory at 0x7f82ebd75948>
>>> a.data
<memory at 0x7f82ebd75888>
>>> a.data
<memory at 0x7f82ebd75948>
回答1:
If you type:
help(a.data)
You will see that it does not return exactly what you expect:
class memoryview(object)
| memoryview(object)
|
| Create a new memoryview object which references the given object.
|
| Methods defined here:
|
It creates a memoryview that references that object. If you want the memory address use id
:
id(a) == id(b)
True
Note that:
id(a) is id(b)
False
Because id(a)
returns an integer and id(b) too and their memory address isn't the same although their values are.
If you want hexadecimal memory:
hex(id(a))
Also, from NumPy doc: numpy.ndarray.data (I really don't know why this .data
is useful but it exists)
回答2:
In [33]: a = np.array([2])
In [34]: b = np.array(a, copy=False)
A nice human-readable way of checking for shared data buffer is the __array_interface__
dictionary.
In [36]: a.__array_interface__
Out[36]:
{'data': (69508768, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (1,),
'version': 3}
In [37]: b.__array_interface__
Out[37]:
{'data': (69508768, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (1,),
'version': 3}
a.data
can be used to make a new array, but otherwise isn't very useful. And even this use is too low-level for most purposes:
In [44]: c = np.ndarray(shape=(1,1), dtype=int, buffer=a.data)
In [45]: c
Out[45]: array([[2]])
In [46]: c.__array_interface__
Out[46]:
{'data': (69508768, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (1, 1),
'version': 3}
来源:https://stackoverflow.com/questions/61102237/how-come-not-copying-a-numpy-array-changes-the-data-attribute