Pandas切片操作:一个很容易忽视的错误

小白学视觉

共 2896字,需浏览 6分钟

 ·

2022-07-22 10:33

点击上方小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

Pandas是一个强大的分析结构化数据的工具集,主要用于数据挖掘和数据分析,同时也提供数据清洗功能。

很多初学者在数据的选取,修改和切片时经常面临一些困惑。这是因为Pandas提供了太多方法可以做同样的事情,方法选择不当,可能导致一些意想不到的错误。 


Pandas切片

 

Pandas数据访问方式包括:df[],.at,.iat,.loc,.iloc(之前有ix方法,pandas1.0之后已被移除)

  • df[] :直接索引
  • at/iat:通过标签或行号获取某个数值的具体位置。
  • loc:通过标签选取数据,即通过index和columns的值进行选取。loc方法有两个参数,按顺序控制行列选取,范围包括start和end。
  • iloc:通过行号选取数据,即通过数据所在的自然行列数为选取数据。iloc方法也有两个参数,按顺序控制行列选取。

它们之间的区别不是文本重点,大家可以新建一个dataframe练习一下,本文我们主要来一个错误示范,然后给大家提一些合理的建议。


错误示范

 

新建一个DataFrame

df = pd.DataFrame({'x':[1,5,4,3,4,5],'y':[.1,.5,.4,.3,.4,.5],'w':[11,15,14,13,14,15]})
x y w0 1 0.1 111 5 0.5 152 4 0.4 143 3 0.3 134 4 0.4 145 5 0.5 15

假设我们要查找与“x”列对应的所有DataFrame元素都大于3,并根据此更改将所有对应的“ y”值更改为50。
我们来先试一个看起来毫无问题的方法

df[df['x']>3]['y']=50
运行之后,df没有任何变化,Warning如下:

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

根据提示信息,我们使用loc方法

df.loc[df['x']>3,'y']=50x     y   w0  1   0.1  111  5  50.0  152  4  50.0  143  3   0.3  134  4  50.0  145  5  50.0  15

得到预期结果√ 

这是为什么呢?这里我们就遇到了所谓的“链接索引”,具体原因是使用了两个索引器,例如:df[][]
df[df['x']>3] 导致Pandas创建原始DataFrame的单独副本
df[df['x']>3]['y'] = 50 将新值分配给“ y”列,但在此临时创建的副本上,而不是原始DataFrame上。

反转切片的顺序时,即先调用列,然后再调用我们要满足的条件,便得到了预期的结果:

df['y'][df['x']>3]=50
x y w0 1 0.1 111 5 50.0 152 4 50.0 143 3 0.3 134 4 50.0 145 5 50.0 15
但是同样会给出一个Warning:A value is trying to be set on a copy of a slice from a DataFrame
SettingWithCopyWarning 是一个警告 Warning,而不是错误 Error。这是因为,当我们从DataFrame中仅选择一列时,Pandas会创建一个视图,而不是副本。关于视图和副本的区别,下图最为形象:
df[]方法会创建视图
dfx    y   w0  1  0.1  111  5  0.5  152  4  0.4  143  3  0.3  134  4  0.4  145  5  0.5  15
z = df['y'] # view of column 'y'z[z>=0.5] = 30
z0 0.11 30.02 0.43 0.34 0.45 30.0
dfx y w0 1 0.1 111 5 30.0 152 4 0.4 143 3 0.3 134 4 0.4 145 5 30.0 15

当我们创建了视图后,pandas就会出现warning,因为它不知道我们是否只想更改y系列(通过z)或原始值df。如果我们要提取“z”作为独立对象怎么办?pandas提供了copy()方法,当我们将命令更新为以下所示的命令时:

z = df['y'].copy()

我们将在内存中创建一个具有其自己地址的全新对象,并且对“z”进行的任何更新df都将不受影响。实际上有两个要点,可以使我们在使用切片和数据操作时免受任何有害影响:

  • 避免链接索引,始终选择.loc/ .iloc(或.at/ .iat)方法;
  • 使用copy() 创建独立的对象,并保护原始资源免遭不当操纵

 

参考

 

https://www.jianshu.com/p/199a653e9668https://www.kdnuggets.com/2020/04/stop-hurting-pandas.html

好消息!

小白学视觉知识星球

开始面向外开放啦👇👇👇




下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲
小白学视觉公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲
小白学视觉公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群


欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~


浏览 29
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报