numpy.ndarray.data attribute buffer object

Question:

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 ?

Asked By: D.L

||

Answers:

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.

Answered By: sj95126

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)
Answered By: hpaulj
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.