Python 与 pandas - 引用和可变性

Python vs pandas - references and mutability

谁能帮我理解这里发生的事情:

a = 1
b = a
b = 2
print(a)
print(b)

这里,显然 a 不会改变,因为将 2 分配给 b 不会改变 a.

在pandas中,但是:

a = pd.DataFrame({'a':[1,2,3]})
b = a
b.iloc[0,0] = 100
print(a)
print(b)

现在为什么 ab 都有 100 而不是 1?当我以为我正在 pandas 中以这种方式创建一个新对象并且不得不使用 b = a.copy() 来避免它时,我刚刚发现我一直在覆盖我的原始变量。

因为在您的第一个示例中,您将两个整数(1 和 2)分配给 a 和 b,它们是两个 不同的 unmutable内存中的对象。

而在您的第二个示例中,a 和 b 被分配了 相同的可变 对象(数据框)。所以在 b 上调用 iloc 方法与在 a 上调​​用它是一样的。

在 pandas 示例中,b = a 不会创建 DataFrame 的副本。内存中只有一个 DataFrame,ba 都是对它的 references。当您更改该对象时,更改在 ab 中都可见,因为它们指向同一事物。

如果要创建数据的副本,您可以写入:

a = pd.DataFrame({'a':[1,2,3]})
b = pd.DataFrame(a, copy=True)

对于Python中的大多数对象都是如此——通常一个变量名只是指向内存中的一个对象,如果你改变了这个对象,所有对它的引用都会受到影响。

第一个例子比较特殊。整数是不可变的(不能改变)所以当你设置 b = 2 时你不会把 1 变成 2,你只是让 b 指向不同的整数,而 a 仍然指向 1.

如果您使用列表而不是整数,结果会有所不同:

a = [1]
b = a
print (a,b)
b[0]=2
print (a,b)

结果:

[1] [1]
[2] [2]