数据索引index
细致的朋友可能会发现一个现象,不论是序列也好,还是数据框也好,对象的最左边总有一个非原始数据对象,这个是什么呢?不错,就是我们接下来要介绍的索引。
在我看来,序列或数据框的索引有两大用处,一个是通过索引值或索引标签获取目标数据,另一个是通过索引,可以使序列或数据框的计算、操作实现自动化对齐,下面我们就来看看这两个功能的应用。
1、通过索引值或索引标签获取数据
In [38]: s4 = pd.Series(np.array([1,1,2,3,5,8]))
In [39]: s4
Out[39]:
0 1
1 1
2 2
3 3
4 5
5 8
dtype: int32
如果不给序列一个指定的索引值,则序列自动生成一个从0开始的自增索引。可以通过index查看序列的索引:
In [40]: s4.index
Out[40]: RangeIndex(start=0, stop=6, step=1)
现在我们为序列设定一个自定义的索引值:
In [41]: s4.index = ['a','b','c','d','e','f']
In [42]: s4
Out[42]:
a 1
b 1
c 2
d 3
e 5
f 8
dtype: int32
序列有了索引,就可以通过索引值或索引标签进行数据的获取:
In [43]: s4[3] # 获取序列的第4个元素
Out[43]: 3
In [44]: s4['e'] # 获取序列中索引为'e'的元素
Out[44]: 5
In [45]: s4[[1,3,5]] # 获取序列的第2,4,6个元素
Out[45]:
b 1
d 3
f 8
dtype: int32
In [46]: s4[['a','b','d','f']]
Out[46]:
a 1
b 1
d 3
f 8
dtype: int32
In [47]: s4[:4]
Out[47]:
a 1
b 1
c 2
d 3
dtype: int32
In [48]: s4['c':]
Out[48]:
c 2
d 3
e 5
f 8
dtype: int32
In [49]: s4['b':'e']
Out[49]:
b 1
c 2
d 3
e 5
dtype: int32
千万注意:如果通过索引标签获取数据的话,末端标签所对应的值是可以返回的(区间左右都是闭合的)!在一维数组中,就无法通过索引标签获取数据,这也是序列不同于一维数组的一个方面。
2、自动化对齐
如果有两个序列,需要对这两个序列进行算术运算,这时索引的存在就体现的它的价值了–自动化对齐。
In [50]: s5 = pd.Series(np.array([10,15,20,30,55,80]),
...: index = ['a','b','c','d','e','f'])
In [51]: s5
Out[51]:
a 10
b 15
c 20
d 30
e 55
f 80
dtype: int32
In [52]: s6 = pd.Series(np.array([12,11,13,15,14,16]),
...: index = ['a','c','g','b','d','f'])
In [53]: s6
Out[53]:
a 12
c 11
g 13
b 15
d 14
f 16
dtype: int32
In [54]: s5 + s6 # 这两个序列在创建时索引顺序是不同的,但计算时按照索引进行了对齐
Out[54]:
a 22.0
b 30.0
c 31.0
d 44.0
e NaN
f 96.0
g NaN
dtype: float64
In [55]: s5/s6
Out[55]:
a 0.833333
b 1.000000
c 1.818182
d 2.142857
e NaN
f 5.000000
g NaN
dtype: float64
由于s5中没有对应的g索引,s6中没有对应的e索引,所以数据的运算会产生两个缺失值NaN。注意,这里的算术结果就实现了两个序列索引的自动对齐,而非简单的将两个序列加总或相除。对于数据框的对齐,不仅仅是行索引的自动对齐,同时也会自动对齐列索引(变量名)。
数据框中同样有索引,而且数据框是二维数组的推广,所以数据框不仅有行索引,而且还存在列索引,关于数据框中的索引相比于序列的应用要强大的多,这部分内容将放在下面的数据查询中讲解。
利用pandas查询数据
这里的查询数据相当于R语言里的subset功能,可以通过布尔索引有针对的选取原数据的子集、指定行、指定列等。我们先导入一个student数据集:
In [56]: student = pd.io.parsers.read_csv('C:\\Users\\admin\\Desktop\\student.csv')
查询数据的前5行或末尾5行:
In [57]: student.head()
Out[57]:
Name Sex Age Height Weight
0 Alfred M 14 69.0 112.5
1 Alice F 13 56.5 84.0
2 Barbara F 13 65.3 98.0
3 Carol F 14 62.8 102.5
4 Henry M 14 63.5 102.5
In [58]: student.tail()
Out[58]:
Name Sex Age Height Weight
14 Philip M 16 72.0 150.0
15 Robert M 12 64.8 128.0
16 Ronald M 15 67.0 133.0
17 Thomas M 11 57.5 85.0
18 William M 15 66.5 112.0
查询指定的行:
In [59]: student.ix[[0,2,4,5,7]] #这里的ix索引标签函数必须是中括号[]
Out[59]:
Name Sex Age Height Weight
0 Alfred M 14 69.0 112.5
2 Barbara F 13 65.3 98.0
4 Henry M 14 63.5 102.5
5 James M 12 57.3 83.0
7 Janet F 15 62.5 112.5
查询指定的列:
In [60]: student[['Name','Height','Weight']].head() #如果多个列的话,必须使用双重中括号
Out[60]:
Name Height Weight
0 Alfred 69.0 112.5
1 Alice 56.5 84.0
2 Barbara 65.3 98.0
3 Carol 62.8 102.5
4 Henry 63.5 102.5
也可以通过ix索引标签查询指定的列:
In [61]: student.ix[:,['Name','Height','Weight']].head()
Out[61]:
Name Height Weight
0 Alfred 69.0 112.5
1 Alice 56.5 84.0
2 Barbara 65.3 98.0
3 Carol 62.8 102.5
4 Henry 63.5 102.5
查询指定的行和列:
In [62]: student.ix[[0,2,4,5,7],['Name','Height','Weight']].head()
Out[62]:
Name Height Weight
0 Alfred 69.0 112.5
2 Barbara 65.3 98.0
4 Henry 63.5 102.5
5 James 57.3 83.0
7 Janet 62.5 112.5
这里简单说明一下ix的用法:df.ix[行索引,列索引]
- ix后面必须是中括号
- 多个行索引或列索引必须用中括号括起来
- 如果选择所有行索引或列索引,则用英文状态下的冒号:表示
以上是从行或列的角度查询数据的子集,现在我们来看看如何通过布尔索引实现数据的子集查询。
查询所有女生的信息:
In [63]: student[student['Sex']=='F']
Out[63]:
Name Sex Age Height Weight
1 Alice F 13 56.5 84.0
2 Barbara F 13 65.3 98.0
3 Carol F 14 62.8 102.5
6 Jane F 12 59.8 84.5
7 Janet F 15 62.5 112.5
10 Joyce F 11 51.3 50.5
11 Judy F 14 64.3 90.0
12 Louise F 12 56.3 77.0
13 Mary F 15 66.5 112.0
查询出所有12岁以上的女生信息:
In [64]: student[(student['Sex']=='F') & (student['Age']>12)]
Out[64]:
Name Sex Age Height Weight
1 Alice F 13 56.5 84.0
2 Barbara F 13 65.3 98.0
3 Carol F 14 62.8 102.5
7 Janet F 15 62.5 112.5
11 Judy F 14 64.3 90.0
13 Mary F 15 66.5 112.0
查询出所有12岁以上的女生姓名、身高和体重:
In [66]: student[(student['Sex']=='F') & (student['Age']>12)][['Name','Height','Weight']]
Out[66]:
Name Height Weight
1 Alice 56.5 84.0
2 Barbara 65.3 98.0
3 Carol 62.8 102.5
7 Janet 62.5 112.5
11 Judy 64.3 90.0
13 Mary 66.5 112.0
上面的查询逻辑其实非常的简单,需要注意的是,如果是多个条件的查询,必须在&(且)或者|(或)的两端条件用括号括起来。
补充一下,除了使用在方括号索引内,布尔索引同样也能用于ix中作为行索引的部分:
>>> df
0 1
a 1 2
b 3 4
c 0 0
>>> df[(df[0]==1) | (df[0]==3)]
0 1
a 1 2
b 3 4
>>> df.ix[(df[0]==1) | (df[0]==3)]
0 1
a 1 2
b 3 4
>>> df.ix[(df[0]==1) | (df[0]==3), 1::-1]
1 0
a 2 1
b 4 3