构建了一个简单的时间序列数据集来说明索引功能
数据索引和选取 pandas对象中的轴标签信息有很多作用:
使用已知指示来确定数据(即提供元数据),这对于分析、可视化以及交互式控制台的显示都十分重要 使能够实现自动和显式的数据对齐 允许直观地获取和设置数据集的子集 在这一部分,我们将致力于最终的目的:即如何切片,切丁以及一般地获取和设置pandas对象的子集。文章将主要集中在Series和DataFrame上,因为它们潜力很大。希望未来在高维数据结构(包括panel)上投入更多的精力,尤其是在基于标签的高级索引方面。
提示:Python和bumpy的索引操作[ ]和属性操作. 为pandas数据结构提供了非常快速和简便的方式。如果你已经知道如何操作Python字典和Numpy数组的话,这就没什么新的了。然而,由于数据的类型无法提前预知,直接使用标准操作将会有一些优化的限制。对于产品代码来说,我们建议你可以利用本文展示的优化的pandas数据使用方法。
警告:一个设置操作是会返回一个复制还是一个引用可能取决于具体情况。这种有时被称为“链式赋值”,我们应当避免这种情况。
警告:在0.15.0版本中,与其他pandas对象一样,index不再是ndarray的子类,而是PandasObject的子类。这个影响不大。
多样的索引方法
为了实现更简便的基于位置的索引,对象选取方法添加了一些用户的请求。pandas现在支持三种类型的多轴索引。
.loc是最基本的基于标签的索引,但是也可以用于布尔数组。当item无法找到时,.loc将会产生KeyError。合法的输入有: 一个单独的标签,如5或“a”,(注意5是作为索引标签,而不是一个整数的位置索引) 一个列表或者数组标签[“a”,”b”,”c”] 一个带有标签“a”:“f”的切片对象(注意,与Python切片相反,这种切片的第一个和最后一个都包含在内!) 一个布尔数组 一个可调用的函数(调用Series, DataFrame或Panel)并返回索引的有效输出(上面中的一个) .iloc是最基本的基于整数位置的索引(从轴的第0位到第length-1位),但是也可以用于布尔数组。除了允许超范围索引的索引器之外,如果一个请求的索引超出了索引范围,.iloc将会产生IndexError。合法的输入有: 一个整数。如5 一个列表或整数数组。如[3,0,4] 一个整型的切片对象,如1:7 一个布尔数组 一个可调用的函数(调用Series, DataFrame或Panel)并返回索引的有效输出(上面中的一个) .ix支持基于整数和标签的混合索引。它主要是基于标签的,但是除非对应的轴是整数类型,否则它将会回到整数位置进行访问。.ix是最普适的,它能够支持.loc和.iloc的任何输入。.ix还支持浮点型的标签。当处理基于位置和标签的混合的层次索引时.ix特别有用。 然而,基于整数的轴只支持基于标签的索引方式,而不支持基于位置的索引。因此,在此种情况下,使用.iloc或者.loc通常会
更加明确。
.loc, .iloc, .ix和[ ]索引能够接受一个可调用对象作为索引器。 使用以下标记从一个多轴对象中获取值(使用.loc为例,但同样适用于.iloc和.ix)。任何的轴访问器都可能是空的切片:假定不规范的轴。(如p.loc[‘a’]等价于p.loc[‘a’,:,:]) Object Type Indexers Series s.loc[indexer] DataFrame df.loc[row_indexer,column_indexer] Panel p.loc[item_indexer,major_indexer,minor_indexer] 基础知识 正如在上一章节中介绍数据结构中所提到的那样,使用[ ]进行索引的主要功能(相当于Python中的__getitem__)是选取出低维切片。因此, 对象类型 选取 返回值类型 Series series[label] 标量值 DataFrame frame[colname] 对应colname的 Series Panel panel[itemname] 对应itemname的DataFrame
这里我们构建了一个简单的时间序列数据集来说明索引功能:
In [1]: dates = pd.date_range('1/1/2000', periods=8) In [2]: df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D']) In [3]: df Out[3]: A B C D 2000-01-01 0.469112 -0.282863 -1.509059 -1.135632 2000-01-02 1.212112 -0.173215 0.119209 -1.044236 2000-01-03 -0.861849 -2.104569 -0.494929 1.071804 2000-01-04 0.721555 -0.706771 -1.039575 0.271860 2000-01-05 -0.424972 0.567020 0.276232 -1.087401 2000-01-06 -0.673690 0.113648 -1.478427 0.524988 2000-01-07 0.404705 0.577046 -1.715002 -1.039268 2000-01-08 -0.370647 -1.157892 -1.344312 0.844885 In [4]: panel = pd.Panel({'one' : df, 'two' : df - df.mean()}) In [5]: panel Out[5]: <class 'pandas.core.panel.Panel'> Dimensions: 2 (items) x 8 (major_axis) x 4 (minor_axis) Items axis: one to two Major_axis axis: 2000-01-01 00:00:00 to 2000-01-08 00:00:00 Minor_axis axis: A to D 注意:除非特殊说明,所有的索引功能都是通用的,不只适用于该时间序列。 因此,根据上述,我们使用[ ]能够实现最基本的索引: In [6]: s = df['A'] In [7]: s[dates[5]] Out[7]: -0.67368970808837059 In [8]: panel['two'] Out[8]: A B C D 2000-01-01 0.409571 0.113086 -0.610826 -0.936507 2000-01-02 1.152571 0.222735 1.017442 -0.845111 2000-01-03 -0.921390 -1.708620 0.403304 1.270929 2000-01-04 0.662014 -0.310822 -0.141342 0.470985 2000-01-05 -0.484513 0.962970 1.174465 -0.888276 2000-01-06 -0.733231 0.509598 -0.580194 0.724113 2000-01-07 0.345164 0.972995 -0.816769 -0.840143 2000-01-08 -0.430188 -0.761943 -0.446079 1.044010 你可以向[ ]中传递列的列表来按照顺序选取多列。如果某列不再DataFrame中,将引发一个异常。也可以通过这种方式设置多个列。 In [9]: df Out[9]: A B C D 2000-01-01 0.469112 -0.282863 -1.509059 -1.135632 2000-01-02 1.212112 -0.173215 0.119209 -1.044236 2000-01-03 -0.8618492881064151 -2.104569 -0.494929 1.071804 2000-01-04 0.721555 -0.706771 -1.039575 0.271860 2000-01-05 -0.424972 0.567020 0.276232 -1.087401 2000-01-06 -0.673690 0.113648 -1.478427 0.524988 2000-01-07 0.404705 0.577046 -1.715002 -1.039268 2000-01-08 -0.370647 -1.157892 -1.344312 0.844885 In [10]: df[['B', 'A']] = df[['A', 'B’]] #交换两个列的值 In [11]: df Out[11]: A B C D 2000-01-01 -0.282863 0.469112 -1.509059 -1.135632 2000-01-02 -0.173215 1.212112 0.119209 -1.044236 2000-01-03 -2.104569 -0.861849 -0.494929 1.071804 2000-01-04 -0.706771 0.721555 -1.039575 0.271860 2000-01-05 0.567020 -0.424972 0.276232 -1.087401 2000-01-06 0.113648 -0.673690 -1.478427 0.524988 2000-01-07 0.577046 0.404705 -1.715002 -1.039268 2000-01-08 -1.157892 -0.370647 -1.344312 0.844885
当将这种变换就地应用到列的子集的时候,你可能会发现这个方法的有用之处。
警告:当从.loc, .iloc和.ix设置Series和DataFrame时,pandas会将所有轴对齐。
这不会改变df,因为在赋值之前就进行了列对齐。
In [12]: df[['A', 'B']] Out[12]: A B 2000-01-01 -0.282863 0.469112 2000-01-02 -0.173215 1.212112 2000-01-03 -2.104569 -0.861849 2000-01-04 -0.706771 0.721555 2000-01-05 0.567020 -0.424972 2000-01-06 0.113648 -0.673690 2000-01-07 0.577046 0.404705 2000-01-08 -1.157892 -0.370647 In [13]: df.loc[:,['B', 'A']] = df[['A', 'B']]#这种方法无法使列A和列B的值对调 In [14]: df[['A', 'B']] Out[14]