理解Pandas的设置复制警告

4 投票
1 回答
925 浏览
提问于 2025-04-29 08:14

我有以下这段代码,但我不太明白为什么会出现这个警告。我看过文档,但还是搞不清楚为什么这样用会导致警告。任何帮助都会很感激。

>>> df = pandas.DataFrame({'a': [1,2,3,4,5,6,7], 'b': [11,22,33,44,55,66,77]})
>>> reduced_df = df[df['a'] > 3]
>>> reduced_df
   a   b
3  4  44
4  5  55
5  6  66
6  7  77
>>> reduced_df['a'] /= 3

Warning (from warnings module):
   File "__main__", line 1
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
>>> reduced_df
          a   b
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77
暂无标签

1 个回答

6

这里的警告是告诉你,尽管看起来你的 reduced_dfdf 的一部分,但实际上它并不是一个引用,而是一个副本。这和我们通常的理解不同,通常我们会认为这样做会得到一个引用,修改这个引用会影响到原来的对象(当然这是针对可变对象来说的):

In [14]:

foo = [0]
bar = foo
bar.append(1)
print(foo,bar)
[0, 1] [0, 1]

所以如果你想修改 df 的某一部分,应该按照警告的建议来做:

In [18]:

df.loc[df['a']>3,'a'] =df['a']/3
df
Out[18]:
          a   b
0  1.000000  11
1  2.000000  22
2  3.000000  33
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77

或者你可以明确地使用 copy() 来创建一个深拷贝,然后在这个副本上进行修改,这样就不会产生任何警告:

In [20]:

reduced_df = df[df['a'] > 3].copy()
reduced_df['a'] /=3
reduced_df
Out[20]:
          a   b
3  1.333333  44
4  1.666667  55
5  2.000000  66
6  2.333333  77

In [21]:
# orig df is unmodified
df
Out[21]:
   a   b
0  1  11
1  2  22
2  3  33
3  4  44
4  5  55
5  6  66
6  7  77

撰写回答