如何检查两个变量是否指向同一个 pandas 对象?

4
在这个例子中,r1和r2引用的是同一个对象,但由于它们的id不同,assert(not r1 is r2)返回false。尽管如此,我原本希望它失败,因为r1和r2都指向同一个对象!!
import pandas as pd
df = pd.DataFrame([0])
r1 = df.iloc[0]
r2 = df.iloc[0]
assert(not r1 is r2)
r1[0] = 1
assert(r1.equals(r2))
print(id(r1), id(r2))

>> 140547055257416 140547055258032

可以在numpy中的数组切片中找到为什么会发生这种情况的解释。


使用'.copy()'。关于为什么,请参见https://dev59.com/6F4c5IYBdhLWcg3wqbwC。 - Michael Gardner
我觉得你误解了我的问题。我已经重新表述了它。 - Chuan
抱歉,这将回答你的问题。https://dev59.com/-VYN5IYBdhLWcg3wFky2 - Michael Gardner
一篇有趣的阅读,但它并没有告诉我如何检查两个变量是否引用同一个 pandas 对象。 - Chuan
你可以称之为一个 bug,但是你是否希望保存每个 iloc 操作以便给出相同的 ID 的字典被保存? - trigonom
2个回答

4

共享内存is之间的主要区别是什么? - Chuan

1

首先,让我们进行一个简单的实验,以查看在 pandas 的意义下,r1r2 实际上是相同的对象

import pandas as pd

df = pd.DataFrame([0,1,2,3])
r1 = df.iloc[:,:1]
r2 = df.iloc[:,:1]

r1.iloc[2] = -10
r2.iloc[1] = -100
assert (not r1 is r2)

print(pd.concat((df,r1,r2),axis=1).to_string())

运行这个脚本,输出是:
     0    0    0
0    0    0    0
1 -100 -100 -100
2  -10  -10  -10
3    3    3    3

这意味着 pandas 认为 r1r2 是同一个对象。请注意,通过运行此脚本实际上可以证明这一点。
unique_ids = []
for _ in range(1000):
    one_id = id(df.iloc[:,:1])
    unique_ids.append(one_id)
set(unique_ids)

你会看到 set(unique_ids) 的长度不为1!!

根据 @user2357112 在 this post 下支持 Monica 的评论

我认为你收到的 ID 与数组元素的地址没有任何关系;它是包含数组元数据和指向元素使用的存储的指针的标头的地址。

基本上,r1r2 是引用相同数组元素的不同对象。


你解释了我的问题,但并没有回答它。你展示了r1和r2被视为同一对象,但id是不同的。 - Chuan
@Chuan请查看我的更新帖子,我猜r1r2是包含数组元数据的标头。 - meTchaikovsky
感谢详细的解释。我标记了Ch3steR的答案为正确答案,因为它回答了问题。 - Chuan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接