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

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

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   w
0  1  0.1  11
1  5  0.5  15
2  4  0.4  14
3  3  0.3  13
4  4  0.4  14
5  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']=50
   x     y   w
0  1   0.1  11
1  5  50.0  15
2  4  50.0  14
3  3   0.3  13
4  4  50.0  14
5  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   w
0  1   0.1  11
1  5  50.0  15
2  4  50.0  14
3  3   0.3  13
4  4  50.0  14
5  5  50.0  15


但是同样会给出一个Warning:A value is trying to be set on a copy of a slice from a DataFrameSettingWithCopyWarning 是一个警告 Warning,而不是错误 Error。这是因为,当我们从DataFrame中仅选择一列时,Pandas会创建一个视图,而不是副本。关于视图和副本的区别,下图最为形象:


640.png

df[]方法会创建视图


df
   x    y   w
0  1  0.1  11
1  5  0.5  15
2  4  0.4  14
3  3  0.3  13
4  4  0.4  14
5  5  0.5  15
z = df['y'] # view of column 'y'
z[z>=0.5] = 30
z
0     0.1
1    30.0
2     0.4
3     0.3
4     0.4
5    30.0
df
   x     y   w
0  1   0.1  11
1  5  30.0  15
2  4   0.4  14
3  3   0.3  13
4  4   0.4  14
5  5  30.0  15


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


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


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


  • 避免链接索引,始终选择.loc/ .iloc(或.at/ .iat)方法;
  • 使用copy() 创建独立的对象,并保护原始资源免遭不当操纵
相关文章
|
4天前
|
数据格式 Python
如何使用Python的Pandas库进行数据透视图(melt/cast)操作?
Pandas的`melt()`和`pivot()`函数用于数据透视。基本步骤:导入pandas,创建DataFrame,然后使用这两个函数转换数据格式。示例代码展示了如何通过`melt()`转为长格式,再用`pivot()`恢复为宽格式。输入数据是包含'Name'和'Age'列的DataFrame,最终结果经过转换后呈现出不同的布局。
46 6
|
4天前
|
JSON 数据挖掘 数据格式
Pandas中Series、DataFrame讲解及操作详解(超详细 附源码)
Pandas中Series、DataFrame讲解及操作详解(超详细 附源码)
123 0
|
8月前
|
数据挖掘 数据建模 索引
【50个Pandas高级操作】(上)
【50个Pandas高级操作】
|
5月前
|
前端开发 Python
Python 教程之 Pandas(13)—— series 上的转换操作
Python 教程之 Pandas(13)—— series 上的转换操作
52 0
|
4天前
|
索引 Python
如何使用Python的Pandas库进行数据透视表(pivot table)操作?
使用Pandas在Python中创建数据透视表的步骤包括:安装Pandas库,导入它,创建或读取数据(如DataFrame),使用`pd.pivot_table()`指定数据框、行索引、列索引和值,计算聚合函数(如平均分),并可打印或保存结果到文件。这允许对数据进行高效汇总和分析。
11 2
|
4天前
|
存储 数据库连接 数据处理
数据加载与保存:Pandas中的数据输入输出操作
【4月更文挑战第16天】Pandas是Python数据分析的强大工具,支持多种数据加载和保存方法。本文介绍了如何使用Pandas读写CSV和Excel文件,以及与数据库交互。`read_csv`和`to_csv`用于CSV操作,`read_excel`和`to_excel`处理Excel文件,而`read_sql`和`to_sql`则用于数据库的读写。了解这些基本操作能提升数据处理的效率和灵活性。
|
4天前
|
数据可视化 Python
如何使用Python的Pandas库进行数据分组和聚合操作?
【2月更文挑战第29天】【2月更文挑战第105篇】如何使用Python的Pandas库进行数据分组和聚合操作?
|
4天前
|
机器学习/深度学习 算法 索引
50个超强的Pandas操作 !!
50个超强的Pandas操作 !!
71 1
|
4天前
|
索引 Python
Python 教程之 Pandas(13)—— series 上的转换操作
Python 教程之 Pandas(13)—— series 上的转换操作
57 0
Python 教程之 Pandas(13)—— series 上的转换操作
|
4天前
|
JSON 数据挖掘 数据库
Pandas 高级教程——IO 操作
Pandas 高级教程——IO 操作
173 2