关于Pandas索引器返回副本/视图规则的行为困惑咨询
Pandas视图与副本的边界行为解析
参考的视图/副本生成规则
- 所有操作默认生成副本;
- 指定
inplace=True则就地修改(仅部分操作支持); .loc/.iloc/.iat/.at这类赋值型索引器会就地修改;- 针对单一数据类型对象的取值型索引器几乎总是返回视图(因内存布局例外情况,不可靠);
- 针对多数据类型对象的取值型索引器总是返回副本。
测试案例1(符合规则预期)
import pandas as pd import numpy as np df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(), 'B': 'one one two three two two one three'.split(), 'C': np.arange(8), 'D': np.arange(8) * 2}) df2 = df.loc[0,] df2[0] = 500
该操作未修改原df,符合规则:df.loc[0,]是针对多数据类型对象的取值型索引器,返回副本,修改副本不会影响原数据。
测试案例2(非预期行为与警告)
df3 = df.iloc[0:2,] df3[:] = 55
执行后触发警告:A value is trying to be set on a copy of a slice from a DataFrame,且原df仅数值型列C、D被修改,字符串型列A、B无变化。按规则,df.iloc[0:2,]应返回副本,为何出现此现象?
问题解析
这源于Pandas的分块存储机制:不同数据类型的列会被存储在独立的内存块中,Pandas会根据列的类型和内存布局做差异化处理:
- 数值型列(C、D)内存布局连续,
df.iloc[0:2,]返回的是视图,共享原数据内存,因此对df3的赋值会直接同步到原df; - 字符串型列(A、B)以
object类型存储,内存布局不连续,df.iloc[0:2,]返回的是副本,修改df3不会影响原df。
这种混合视图与副本的状态,就是警告的触发原因——Pandas无法确认你的修改意图,因此抛出警告提示潜在的非预期行为。
需要注意的是,之前参考的规则是简化总结,实际Pandas会基于内存效率做优化,从而出现这类边界情况。
内容的提问来源于stack exchange,提问作者P.Jo
相关产品推荐
相关产品推荐

