I create different numpy
arrays as follows:
import numpy as np
a = np.array([[1,2,3],[1,2,3]]) # 2d array of integers
b = np.array([[1,2,3],[1,2,5.0]]) # 2d array of floats
c = np.array([1,2,3,4,5,6,7,8,9]) # 1d array of integers
d = np.array([10,20,30]) # different 1d array of integers
# python buffer object pointing to the start of the arrays data.
print(a.data)
print(b.data)
print(c.data)
print(d.data)
According to the numpy docs i expect to get a "python buffer object pointing to the start of the arrays data". Here is the official doc (from the numpy website): https://numpy.org/doc/stable/reference/generated/numpy.ndarray.data.html
So i would expect a different memory address for each array.
but i get this:
<memory at 0x000001EAE8B7CAD0>
<memory at 0x000001EAE8B7CAD0>
<memory at 0x000001EAE98E8A00>
<memory at 0x000001EAE98E8A00>
- The first two have the same memory buffer object pointer.
- And the second two have the same memory buffer object pointer.
Is numpy
inferring the memory buffer object pointer based on the dimension of the array or if not, what is the rule that generates similar pointer addresses ?
CodePudding user response:
They aren't sharing the same memory. .data
creates a memoryview object every time the attribute is accessed.
You can see from this session that it's a different address every time:
>>> d.data
<memory at 0x6ffff70bddc0>
>>> d.data
<memory at 0x6ffff70bdb80>
>>> d.data
<memory at 0x6ffff70bd1c0>
In your case, the object is reclaimed immediately after print()
and the next one created happens to have the same address.
CodePudding user response:
In an ipython session:
In [38]: type(a.data)
Out[38]: memoryview
and the docs
for that object:
In [39]: a.data?
Type: memoryview
String form: <memory at 0x000002AE38BAF5F0>
Length: 2
Docstring: Create a new memoryview object which references the given object.
The print string of a memory view doesn't tell us anything about the databuffer address.
It can be used to make a view
of the the array:
In [45]: aa = np.ndarray(a.shape, a.dtype, buffer=a.data)
In [46]: aa
Out[46]:
array([[1, 2, 3],
[1, 2, 3]])
In [47]: aa.base is a
Out[47]: True
The data
of __array_interface__
is closer to being a numeric address of the underlying data buffer. I don't think it can be used in code, but I find it useful when checking whether an array is a view or copy:
In [48]: a.__array_interface__
Out[48]:
{'data': (2947257325392, False),
'strides': None,
'descr': [('', '<i4')],
'typestr': '<i4',
'shape': (2, 3),
'version': 3}
In [49]: aa.__array_interface__['data']
Out[49]: (2947257325392, False)