先看看下面的代码
import numpy as np import pandas as pd np.random.seed(100) data = pd.DataFrame(np.random.randint(1, 10, size=(3, 4)), columns=list('abcd')) print(data) ### data2 = data['a'] data2['e'] = data['a'] - data['b'] print(type(data2)) # <class 'pandas.core.series.Series'> print(data2) # 0 9 # 1 8 # 2 6 # e 0 0 # 1 7 # 2 3 # dtype: int32 # Name: a, dtype: object 啥也不是,不是我们想要的 ### data3 = pd.DataFrame(data['a']) # 手动生成一个新的 df data3['e'] = data['a'] - data['b'] print(data3) # a e # 0 9 0 # 1 8 7 # 2 6 3 ### data4 = data[['a', 'b']] # data4['e'] = data['a'] - data['b'] # print(data4) # 报错如下 # A value is trying to be set on a copy of a slice from a DataFrame. # Try using .loc[row_indexer,col_indexer] = value instead
data 是一个 DataFrame,
data2 取了一列,得到一个 Series,竟然也能再添加一列,不过结果乱七八糟;
data3 也取了一列,手动生成 DataFrame,再添加一列,正常;
data4 取了两列,再添加一列,问题来了,报错
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
问题分析:
data4 选择了 df 的一部分,然后对其进行修改,此时 pandas 无法确定是在原来的 df 上做修改,还是复制一个新的 df 出来单独操作;
解决办法有3个:
1. copy 函数,明确复制出来一个
2. loc 选择器,也是明确复制一部分数据
3. 手动生成新的 df
## 解决方法1:copy方法 data4 = data[['a', 'b']].copy() data4['e'] = data['a'] - data['b'] print(data4) # a b e # 0 9 9 0 # 1 8 1 7 # 2 6 3 3 ## 解决方法2:loc选择器 data4 = data.loc[:, ['a', 'b']] data4['e'] = data['a'] - data['b'] print(data4) # a b e # 0 9 9 0 # 1 8 1 7 # 2 6 3 3 print(data) ## 解决方法3:手动生成DF data4 = pd.DataFrame(data[['a', 'b']]) data4['e'] = data['a'] - data['b'] print(data4)
更多理论见 参考资料2
参考资料:
http://www.python66.com/pandasshujufenxi/284.html
https://www.jianshu.com/p/72274ccb647a Pandas 中 SettingwithCopyWarning 的原理和解决方案
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)