Pandas中的重新赋值:复制还是视图?

3 投票
1 回答
4991 浏览
提问于 2025-04-17 23:09

假设我们有一个如下的数据表:

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                          'foo', 'bar', 'foo', 'foo'],  
                   'B' : ['one', 'one', 'two', 'three',
                          'two', 'two', 'one', 'three'],
                   'C' : randn(8), 'D' : randn(8)})

如下所示:

> df
     A      B         C         D
0  foo    one  0.846192  0.478651
1  bar    one  2.352421  0.141416
2  foo    two -1.413699 -0.577435
3  bar  three  0.569572 -0.508984
4  foo    two -1.384092  0.659098
5  bar    two  0.845167 -0.381740
6  foo    one  3.355336 -0.791471
7  foo  three  0.303303  0.452966

然后我做了以下操作:

df2 = df
df  = df[df['C']>0]

如果你现在查看 dfdf2,你会发现 df2 保留了原始数据,而 df 被更新为只保留了 C 大于 0 的值。

我原以为在像 df2 = df 这样的赋值中,Pandas 不会创建副本,只有在以下情况下才会创建副本:

  1. df2 = df.copy(deep=True)
  2. df2 = copy.deepcopy(df)

那么上面发生了什么呢?df2 = df 是不是创建了一个副本?我猜答案是没有,所以应该是 df = df[df['C']>0] 创建了一个副本。我推测,如果我上面没有 df2=df,那么内存中会有一个没有任何引用的副本漂浮着。这是正确的吗?

注意:我读过 返回视图与副本,我想知道以下内容是否解释了这种行为:

每当涉及标签数组或布尔向量进行索引操作时,结果将是一个副本。

这是否解释了这种行为。

1 个回答

7

并不是说 df2 在复制,而是 df = df[df['C'] > 0] 这行代码返回了一个副本。

你只需要打印出这些 ID,就能看到结果:

print id(df)
df2 = df
print id(df2)
df = df[df['C'] > 0]
print id(df)

撰写回答