0

As the below code shows, 3-dimension ndarray b is the view of one-dimension a.
Per my understanding, b[1,0,3] and a[11] should refer to same object with value 11.
But from the print result, id(a[11]) and id(b[1,0,3]) are different.

Isn't id represent the memory address of an object?
If yes, why are the memory addresses different for same object?

import numpy as np
a = np.arange(16)
b = a.reshape(2,2,4)
print(a)
print(b)
print(a[11])
print(b[1,0,3])

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15]

[[[ 0  1  2  3]
  [ 4  5  6  7]]

 [[ 8  9 10 11]
  [12 13 14 15]]]

11
11

print(hex(id(a[11])))
print(hex(id(b[1,0,3])))

0x23d456cecf0
0x23d456ce950
macyou
  • 99
  • 6
  • 1
    Elements of arrays do not have `id`. `numpy` arrays don't store python objects. – hpaulj Feb 17 '21 at 16:06
  • Thanks for the answer! Do you know any documents introduce the concept that id function should not be applied to non-native python objects? – macyou Feb 17 '21 at 17:47
  • This has been discussed in a number of previous SO questions. The key is to understand how `numpy` arrays are stored (`shape`, `dtype`, `data buffer`), and what happens when you index an element. It returns a `value`, not a `reference` (as `list` does). – hpaulj Feb 17 '21 at 18:45
  • 1
    An answer, https://stackoverflow.com/questions/63891689/multiple-elements-of-numpy-array-has-same-id, with links to more answers. – hpaulj Feb 17 '21 at 19:12
  • Great thanks for your help! After looping through those answers, now I realize it's absolutely not easy to write efficient programs with python – macyou Feb 17 '21 at 20:30

2 Answers2

1

When you apply reshape it doesn't necessarily store b in the same memory location. Refer to the documentation, which says:

Returns: reshaped_array : ndarray

This will be a new view object if possible; otherwise, it will be a copy. Note there is no guarantee of the memory layout (C- or Fortran- contiguous) of the returned array.

Hence, even though both of them have the same value (i.e 11), they are stored in different memory locations.

Ishwar Venugopal
  • 872
  • 6
  • 17
  • His `b` is a `view`. But the `id` of an indexed element doesn't tell us anything about the array's databuffer. – hpaulj Feb 17 '21 at 16:09
0

Per definition, id function will return address of the object in memory for CPython.
Based on @hpaulj comment, if object is a non-native Python object, id() will return meaningless result.
It doesn't make sense to call id function on non-python object of ndarray.
That's why id of ndarray elements looks wired.

Return the “identity” of an object. This is an integer (or long integer) which is
guaranteed to be unique and constant for this object during its lifetime.
Two objects with non-overlapping lifetimes may have the same id() value.
CPython implementation detail: This is the address of the object in memory.

The result of invoking id() on native python array elements works as expected and return continuous memory addresses of array elements as below:

    import array
    pa = array.array('l', [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
    print(pa)
    for i in range(16):
        print(pa[i],"=>",hex(id(pa[i])))

    array('l', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
    0 => 0x7ffe63d01680
    1 => 0x7ffe63d016a0
    2 => 0x7ffe63d016c0
    3 => 0x7ffe63d016e0
    4 => 0x7ffe63d01700
    5 => 0x7ffe63d01720
    6 => 0x7ffe63d01740
    7 => 0x7ffe63d01760
    8 => 0x7ffe63d01780
    9 => 0x7ffe63d017a0
    10 => 0x7ffe63d017c0
    11 => 0x7ffe63d017e0
    12 => 0x7ffe63d01800
    13 => 0x7ffe63d01820
    14 => 0x7ffe63d01840
    15 => 0x7ffe63d01860

Call id on ndarray element which is non-native python object returns meaningless result as below(Eg:aa[0],aa[2],aa[4] return same id):

    import platform 
    print(platform.python_implementation())
    aa = np.arange(16)
    print(aa)
    for i in range(16):
        print(aa[i],"=>",hex(id(aa[i])))

    CPython
    [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15]
    0 => 0x23d4913ba70
    1 => 0x23d4913ba90
    2 => 0x23d4913ba70
    3 => 0x23d4913ba90
    4 => 0x23d4913ba70
    5 => 0x23d4913ba90
    6 => 0x23d4913ba90
    7 => 0x23d4913b570
    8 => 0x23d4913b570
    9 => 0x23d4913b710
    10 => 0x23d4913b570
    11 => 0x23d4913b710
    12 => 0x23d4913b570
    13 => 0x23d4913b710
    14 => 0x23d4913b570
    15 => 0x23d4913b550
macyou
  • 99
  • 6