当前位置: 首页 > 后端技术 > Python

Pandas切片操作:SettingWithCopyWarning

时间:2023-03-26 00:44:07 Python

Pandas是一个强大的工具集,用于分析容易被忽略的结构化数据。主要用于数据挖掘和数据分析,也提供数据清洗功能。许多初学者在选择、修改和切片数据时,常常会遇到一些困惑。这是因为Pandas提供了太多的方法来做同样的事情,方法选择不当可能会导致一些意想不到的错误。Pandas切片Pandas数据访问方式包括:df[],.at,.iat,.loc,.iloc(之前有ix方式,pandas1.0后去掉)df[]:直接索引at/iat:通过标签或行号来获取一个值的具体位置。loc:按标签选择数据,即按索引和列的值选择。loc方法有两个参数,分别控制行和列的选择顺序,范围包括开始和结束。iloc:按行号选择数据,即按数据所在的自然行数和列数选择数据。iloc方法还有两个参数,分别控制行和列的选择顺序。它们之间的区别不是本文的重点。您可以创建一个新的数据框来练习。在这篇文章中,我们将主要演示一个错误,然后给你一些合理的建议。报错演示新建DataFramedf=pd.DataFrame({'x':[1,5,4,3,4,5],'y':[.1,.5,.4,.3,.4,.5],'w':[11,15,14,13,14,15]})xyw010.111150.515240.414330.313440.414550.515假设我们要查找所有DataFrame列对应的元素都大于3,所有对应的“y”值都根据这个变化改为50。我们试试一个貌似没有问题的方法df[df['x']>3]['y']=50运行后df没有变化,Warning如下:Avalueistryingto设置在DataFrame的切片副本上。尝试使用.loc[row_indexer,col_indexer]=value代替根据提示信息,我们使用loc方法df.loc[df['x']>3,'y']=50xyw010.1111550.0152450.014330.3134450.0145550.015得到预期结果√这是为什么呢?这里我们遇到所谓的“链接索引”,具体是由于使用了两个索引器,例如:df[][]df[df['x']>3]导致Pandas创建原始DataFrame的单独副本df[df['x']>3]['y']=50给'y'列赋新值,但是在这个临时创建的副本上,而不是原来的DataFrame。当反转切片的顺序时,即先调用列,然后调用我们想要满足的条件,我得到了预期的结果:df['y'][df['x']>3]=50xyw010.1111550.0152450.014330.3134450.0145550.015但它也会发出警告:尝试在DataFrameSettingWithCopyWarning的切片副本上设置值是警告,而不是错误。这是因为,当我们只从DataFrame中选择一列时,Pandas会创建一个视图,而不是副本。关于view和copy的区别,下图最形象:df[]方法会创建viewdfxyw010.111150.515240.414330.313440.414550.515z=df['y']#列'y'z[z>=0.5]=30z00.1130.020.430.340.4530.0dfxyw010.1111530.015240.414330.313440.4145530.0在我们创建15之后asview出现警告是因为它不知道我们只是想改变y系列(通过z)还是原始值df。如果我们想将“z”提取为独立对象怎么办?pandas提供了copy()方法,当我们将命令更新为这样的东西时:z=df['y'].copy()我们将在内存中创建一个具有自己地址的全新对象,并对df所做的任何更新按“z”将不受影响。实际上有两点可以使我们在使用切片和数据操作时免受任何有害影响:避免链接索引。始终选择.loc/.iloc(或.at/.iat)方法;使用copy()创建独立对象并保护原始资源免受不当操作。参考https://www.jianshu.com/p/199...https://www.kdnuggets.com/202...