Reputation: 55
I tried to understand the difference caused by numpy "2D" arrays, that is, numpy.zeros((3, )), numpy.zeros((3, 1)), numpy.zeros((1, 3)).
I used id
to look at the memory allocation for each element. But I found some weird outputs in iPython console.
a = np.zeros((1, 3))
In [174]: id(a[0, 0])
Out[174]: 4491074656
In [175]: id(a[0, 1])
Out[175]: 4491074680
In [176]: id(a[0, 2])
Out[176]: 4491074704
In [177]: id(a[0, 0])
Out[177]: 4491074728
In [178]: id(a[0, 1])
Out[178]: 4491074800
In [179]: id(a)
Out[179]: 4492226688
In [180]: id(a[0, 1])
Out[180]: 4491074752
The memories of the elements are
Moreover, the elements in the array of shape (1, 3) seem to be of successive memory at first, but it's not even the case for other shapes, like
In [186]: a = np.zeros((3, ))
In [187]: id(a)
Out[187]: 4490927280
In [188]: id(a[0])
Out[188]: 4491075040
In [189]: id(a[1])
Out[189]: 4491074968
In [191]: a = np.random.rand(4, 1)
In [192]: id(a)
Out[192]: 4491777648
In [193]: id(a[0])
Out[193]: 4491413504
In [194]: id(a[1])
Out[194]: 4479900048
In [195]: id(a[2])
Out[195]: 4491648416
I am actually not quite sure whether id
is suitable to check memory in Python. From my knowledge I guess there is no easy way to get the physical address of variables in Python.
Just like C or Java, I expect the elements in such "2D" arrays should be consecutive in memory, which seems not to be true. Besides, the results of id
are keeping changing, which really confuses me.
I am interested in this because I am using mpi4py a little bit, and I wanna figure out how the variables are sent/received between CPUs.
Upvotes: 4
Views: 5541
Reputation: 97301
Numpy array saves its data in a memory area seperated from the object itself. As following image shows:
To get the address of the data you need to create views of the array and check the ctypes.data
attribute which
is the address of the first data element:
import numpy as np
a = np.zeros((3, 2))
print(a.ctypes.data)
print(a[0:1, 0].ctypes.data)
print(a[0:1, 1].ctypes.data)
print(a[1:2, 0].ctypes.data)
print(a[1:2, 1].ctypes.data)
Upvotes: 5