为何修改判定为副本的DataFrame切片会改变原DataFrame?
Pandas中
_is_view为False但修改切片仍改变原DataFrame的原因解释 问题描述
创建DataFrame后,检查df.loc[[True, True, False],'a']的_is_view属性为False,认为这是原DataFrame的副本,按预期修改该副本不应改变原DataFrame。但执行df.loc[[True, True, False],'a'] = 'abcd'后,原DataFrame却被修改了,现解释这一行为。
代码示例
import pandas as pd df = pd.DataFrame({'a':[1,2,3],'b':['x','y','z']}) # 查看切片的_is_view属性 print(df.loc[[True, True, False],'a']._is_view) # 输出: False
# 对切片执行赋值操作 df.loc[[True, True, False],'a'] = 'abcd' print(df) # 输出: # a b # 0 abcd x # 1 abcd y # 2 3 z
原因解释
_is_view是内部属性,不能作为判断依据:_is_view属于pandas的内部实现细节,官方不推荐用户用它来区分视图和副本。它的返回结果受索引方式、数据结构、内存布局等多种因素影响,无法准确反映赋值操作对原数据的影响。- 赋值操作直接作用于原数据:当执行
df.loc[索引] = 值这类语句时,这是原地赋值逻辑。pandas会通过loc索引器直接定位到原DataFrame的对应位置,直接修改原数据的内存区域,而非先创建副本、修改副本再替换。哪怕df.loc[索引]返回的是副本对象,赋值操作也不会作用在这个副本上,而是绕过它直接操作原DataFrame。 - 临时对象的误区:
df.loc[[True, True, False],'a']是临时生成的对象,_is_view描述的是这个临时对象的属性,但赋值语句的目标并非这个临时对象——pandas的赋值语法是通过索引器直接映射到原数据的,和临时对象是否为视图/副本无关。
内容的提问来源于stack exchange,提问作者figs_and_nuts
相关产品推荐
相关产品推荐

