简体   繁体   中英

why does same element of an ndarray have different id in numpy?

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

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 (ie 11), they are stored in different memory locations.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM