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)
现在为什么 a
和 b
都有 100
而不是 1
?当我以为我正在 pandas 中以这种方式创建一个新对象并且不得不使用 b = a.copy()
来避免它时,我刚刚发现我一直在覆盖我的原始变量。
因为在您的第一个示例中,您将两个整数(1 和 2)分配给 a 和 b,它们是两个 不同的 unmutable内存中的对象。
而在您的第二个示例中,a 和 b 被分配了 相同的可变 对象(数据框)。所以在 b 上调用 iloc
方法与在 a 上调用它是一样的。
在 pandas 示例中,b = a
不会创建 DataFrame 的副本。内存中只有一个 DataFrame,b
和 a
都是对它的 references。当您更改该对象时,更改在 a
和 b
中都可见,因为它们指向同一事物。
如果要创建数据的副本,您可以写入:
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]
谁能帮我理解这里发生的事情:
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)
现在为什么 a
和 b
都有 100
而不是 1
?当我以为我正在 pandas 中以这种方式创建一个新对象并且不得不使用 b = a.copy()
来避免它时,我刚刚发现我一直在覆盖我的原始变量。
因为在您的第一个示例中,您将两个整数(1 和 2)分配给 a 和 b,它们是两个 不同的 unmutable内存中的对象。
而在您的第二个示例中,a 和 b 被分配了 相同的可变 对象(数据框)。所以在 b 上调用 iloc
方法与在 a 上调用它是一样的。
在 pandas 示例中,b = a
不会创建 DataFrame 的副本。内存中只有一个 DataFrame,b
和 a
都是对它的 references。当您更改该对象时,更改在 a
和 b
中都可见,因为它们指向同一事物。
如果要创建数据的副本,您可以写入:
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]