最近在写个性化推荐的论文,经常用到Python来处理数据,被pandas和numpy中的数据选取和索引问题绕的比较迷糊,索性把这篇官方文档翻译出来,方便自查和学习,翻译过程中难免很多不到位的地方,但大致能看懂,错误之处欢迎指正~
pandas对象中的轴标签信息有很多作用:
· 使用已知指标来标识数据(即提供元数据),这对于分析、可视化以及交互式控制台的显示都十分重要
· 使能够实现自动和显式的数据对齐
· 允许直观地获取和设置数据集的子集
在这一部分,我们将关注最终的目的:即如何切片,切丁以及一般地获取和设置pandas对象的子集。文章将主要集中在Series和DataFrame上,因为它们在这方面潜力很大。提示:Python和Numpy的索引操作“[ ]”和属性操作“.”为pandas数据结构提供了非常快速和简便的方式。它们能给使交互工作更为直观,如果你已经知道如何操作Python字典和Numpy数组的话,那就没什么新的东西可以学习了。然而,由于数据的类型无法提前预知,直接使用标准操作将会有一些优化的限制。对于产品代码来说,我们建议你可以利用本文展示的优化的pandas数据使用方法。警告:一个设置操作是会返回一个副本还是一个引用可能取决于具体情况。这种有时被称为“链式赋值”,我们应当避免这种情况。请参见返回视图与副本。警告:在0.18.0中对基于浮点的整数索引的变化进行了总结说明,请参见这里。
多索引和更高级的索引文档请参见多索引/高级索引。
一些先进的策略见菜谱。
多样的索引方法
为了实现更简便的基于位置的索引,对象选取方法添加了一些用户的请求。pandas现在支持三种类型的多轴索引。
.loc是最基本的基于标签的索引,但是也可以用于布尔数组。当item无法找到时,.loc将会产生KeyError。合法的输入有:
· 一个单独的标签,如5或“a”,(注意5是作为索引标签,而不是一个整数的位置索引)
· 一个列表或者数组标签[“a”,”b”,”c”]
· 一个带有标签“a”:“f”的切片对象(注意,与Python切片相反,这种切片的第一个和最后一个都包含在内!请参见标签切片。)
· 一个布尔数组
· 一个可调用的函数(调用Series, DataFrame或Panel)并返回索引的有效输出(上面中的一个)
.iloc主要是基于整数位置的索引(从轴的第0位到第length-1位),但是也可以用于布尔数组。除了允许超范围索引的索引器之外,如果一个请求的索引超出了索引范围,.iloc将会产生IndexError。合法的输入有:
· 一个整数。如5
· 一个列表或整数数组。如[4,3,0]
· 一个整型的切片对象,如1:7
· 一个布尔数组
· 一个可调用的函数(调用Series, DataFrame或Panel)并返回索引的有效输出(上面中的一个)
.loc, .iloc和[ ]索引能够接受一个可调用对象作为索引器。更多请参见基于可调用对象的选取。
使用以下标记从一个多轴对象中获取值(使用.loc为例,但同样适用于.iloc)。任何的轴访问器都可能是空的切片:假定不规范的轴。(如p.loc[‘a’]等价于p.loc[‘a’,:,:])
基础知识
正如在上一章节中介绍数据结构中所提到的那样,使用[ ]进行索引的主要功能(相当于Python中的__getitem__)是选取出低维切片。下面的表显示了使用[ ]索引pandas对象时返回值的类型:
对象类型 选取 返回值类型
Series series[label] 标量值
DataFrame frame[colname] 对应colname的Series
Panel panel[itemname] 对应itemname的DataFrame
这里我们构建了一个简单的时间序列数据集来说明索引功能:
注意:除非特殊说明,所有的索引功能都是通用的,不只适用于该时间序列。
因此,根据上述,我们使用[ ]能够实现最基本的索引:
你可以向[ ]中传递列的列表来按照顺序选取多列。如果某列不在DataFrame中,将引发一个异常。也可以通过这种方式设置多个列。
当将这种变换就地应用到列的子集的时候,你可能会发现这个方法的有用之处。警告:当从.loc, .iloc设置Series和DataFrame时,pandas会将所有轴对齐。
这不会改变df,因为在赋值之前就进行了列对齐。
正确的做法是使用原始值
属性访问
你或许能够直接把Series的index,一个DataFrame的column,一个Panel的item作为一种属性来访问。
警告:
· 只有当索引元素是一个有效的Python标识符时才能使用这种方式进行访问,比如s.1就不可以。请参照关于有效标识符的解释。
· 如果属性和现存的方法名冲突的话,这种方式也不可行。如s.min
· 同样,如果属性名和任意一个如下的名字冲突的话也不可行:index,major_axis, minor_axis, items。
· 无论哪种情况,标准的索引总是可行的,如s[“1”], s[“min”]和s[“index”]都能够访问相应的元素或列。
如果你使用的是IPython的环境,你也可以使用tab-完成键来查看这些访问属性。
你也可以向一个DataFrame的一行分配一个dict。
你可以使用属性访问来修改一个Series或DataFrame的一个列中已有的元素,但是要谨慎操作;如果你试图使用属性访问来创建一列的话,它将会创建一个新的属性,而不是新列。在0.21.0和之后的版本里,该操作将会报出UserWarning:
切片范围
在沿任意轴的切片方法中,鲁棒性和一致性最强的方法是在使用位置选择部分详细介绍的.iloc方法。现在,我们介绍一下使用[ ]操作进行切片的语法。
对于Series来说,这个语法对应的就是ndarray,返回的是值的切片和相关的标签:
需要注意的是设置操作也是如此:
对于DataFrame来说,在[ ]中的切片是对行的操作。由于它的普适性,所以这样非常方便。
使用标签选择警告:对于一个设置操作,是返回一个副本还是引用取决于当时的上下文。这叫做“链式赋值”,这种情况应当避免。请参见返回视图与副本。警告:当你的切片器与索引类型不兼容(或不可转换)时,.loc是非常严格的。例如在一个DatatimeIndex中使用整数的话,将会引发一个Type