Вы не получаете идентификатор «ячейки», вы получаете id
объекта, возвращенного аксессором .loc
, который является коробочной версией базовых данных.
Итак,
>>> import pandas as pd
>>> df = pd.DataFrame(columns=list('abc'), data=np.arange(18).reshape(6, 3))
>>> df1 = df.iloc[:3, :]
>>> df.dtypes
a int64
b int64
c int64
dtype: object
>>> df1.dtypes
a int64
b int64
c int64
dtype: object
Но поскольку все в Python является объектом, ваш метод loc
должен возвращать объект:
>>> x = df.loc[0, 'a']
>>> x
0
>>> type(x)
<class 'numpy.int64'>
>>> isinstance(x, object)
True
Однако фактический базовый буферпримитивный массив из 64-битных целых чисел со знаком фиксированного размера.Они не являются объектами Python, они «упакованы» для заимствования термина из других языков, которые смешивают примитивные типы с объектами.
Теперь явление, которое вы видите со всеми объектами, имеющими одинаковые id
:
>>> id(df.loc[0, 'a']), id(df.loc[0, 'a'])
(4539673432, 4539673432)
>>> id(df.loc[0, 'a']), id(df.loc[0, 'a']), id(df1.loc[0,'a'])
(4539673432, 4539673432, 4539673432)
Происходит потому, что в Python объекты могут повторно использовать адрес памяти недавно восстановленных объектов.Действительно, когда вы создаете свой кортеж из id
, объект, возвращенный loc
, существует только достаточно долго, чтобы его можно было передать и обработать при первом вызове id
, во второй раз, когда вы используете loc
, объектуже освобожден, просто повторно использует ту же память.Вы можете увидеть то же поведение с любым объектом Python, например list
:
>>> id([]), id([])
(4545276872, 4545276872)
По сути, id
гарантированно будут уникальными только для времени жизни объект.Подробнее об этом явлении здесь .Но обратите внимание, что в следующем случае он всегда будет другим:
>>> x = df.loc[0, 'a']
>>> x2 = df.loc[0, 'a']
>>> id(x), id(x2)
(4539673432, 4539673408)
Поскольку вы сохраняете ссылки вокруг, объекты не возвращаются и требуют новой памяти.
Примечание, дляВо многих неизменяемых объектах интерпретатор может оптимизировать и вернуть точно такой же объект .В CPython это относится к «маленьким целым», так называемому кешу small-int:
>>> x = 2
>>> y = 2
>>> id(x), id(y)
(4304820368, 4304820368)
Но это деталь реализации, на которую не следует полагаться.
ЕслиВы хотите доказать себе, что ваши фреймы данных совместно используют один и тот же базовый буфер, просто измените их, и вы увидите одно и то же изменение, отраженное между представлениями:
>>> df
a b c
0 0 1 2
1 3 4 5
2 6 7 8
3 9 10 11
4 12 13 14
5 15 16 17
>>> df1
a b c
0 0 1 2
1 3 4 5
2 6 7 8
>>> df.loc[0, 'a'] = 99
>>> df
a b c
0 99 1 2
1 3 4 5
2 6 7 8
3 9 10 11
4 12 13 14
5 15 16 17
>>> df1
a b c
0 99 1 2
1 3 4 5
2 6 7 8