利用python进行数据分析
第五章:pandas入门
第二节,基本功能
1,重新索引
在pandas中reindex能够创建一个适应新索引的新对象 >>> obj=Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
>>> obj
d 4.5
b 7.2
a -5.3
c 3.6
调用该Series的reindex将会根据新索引进行重排 >>> obj2.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
>>> obj2
a -5.3
b 7.2
c 3.6
d 4.5
e 0.0
fill_ value是给’e’这个索引赋值,如果不加入fill_value则引入缺失值
对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可达到此目的,例如,使用ffill可实现前向值填充: >>> obj3=Series(['blue', 'putple', 'yellow'], index=[0, 2, 4])
>>> obj3.reindex(range(6), method='ffill')
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
表5-4:reindex(插值)method选项
| 参数 | 说明 |
| ffill或pad | 前向填充(或搬运)值 |
| bfill或backfill | 后向填充(或搬运)值 |
对于DataFrame,reindex可以修改(行)索引,列,或两个都修改。如果仅传入一个序列,则会重新索引行: >>> frame = DataFrame(np.arrange(9).reshape((3, 3)), index=['a', 'c', 'd'], columes=['Ohio', 'Texas', 'California']
>> frame
··Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
>>> frame.reindex(['a', 'b', 'c', 'd'])
#从新加入‘b’行索引 ··Ohio Texas California
a 0 1 2
b NaN NaN NaN
c 3 4 5
d 6 7 8
>>> frame.reindex(columes=['Texas', 'Utah', 'California'])
#从新定义‘Utah’这个列索引,但‘Utah’这个列没有定义数值 ··Texas Utah California
a 1 NaN 2
c 2 NaN 5
d 7 NaN 8
>>> frame.reindex(index=['a', 'b', 'c', 'd'], method='fill', columns=['Texas', 'Utah', 'California'])
#从新加入了行索引‘b’,并利用fill向前填充数值 ··Texas Utah California
a 1 NaN 2
b 1 NaN 2
c 2 NaN 5
d 7 NaN 8
表5-5:reindex函数的参数
| 参数 | 说明 |
| index | 用作索引的新序列,既可能是Index实例,也可以是其他序列型的Python数据结构。Index 会被完全使用,就像没有任何复制一样 |
| method | 插值(填充)方式,可见前表内容 |
| fill_value | 在重新索引的过程中,需要引入缺失值的使用的替代值 |
| limit | 前向或后向填充时的最大填充量 |
| level | 在MultiIndex的指定级别上匹配简单索引,否则选取其子集 |
| copy | 默认为True,无论如何都复制;如果为FALSE,则新旧相等就不复制 |
2,丢弃指定轴上的项
drop方法可实现斗气某条轴上的一个或多个相,并返回一个在指定轴上删除了指定值的新对象 >>> obj=Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
new_obj=obj.drop('c')
a 0
b 1
d 3
e 4
>>> obj.drop(['d', 'c'])
a 0
b 1
e 4
同时DataFrame,可以删除任意轴上的索引值 >>> data2=DataFrame(np.arange(16).reshape((4, 4)), index=['Ohio', 'Colorado', 'Utah', 'New York'], columns=['one', 'two', 'three', 'four'])
>>> data2
····one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
>>> data2.drop(['Ohio', 'Colorado'])
#横向索引可通过在drop()函数中输入取出索引的列表方法得到取值 ····one two three four
Utah 8 9 10 11
New York 12 13 14 15
>>> data2.drop(['two', 'four'], axis=1)
#纵向索引取值需要在drop()函数中加入axis=1这个参数 ····one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
blastp_out.columns=['query','subject','identity','align_length','mismatches','gap_opens','q_start','q_end','s_start','s_end','evalue','bit_score']
#加入列名
3,索引、选取和过滤
对于DataFrame进行索引其实就是获取一个或多个列 >>> data2['two']
Ohio 1
Colorado 5
Utah 9
New York 13
Name: two, dtype: int64
>>> data2[['one', 'three']]
····one three
Ohio 0 2
Colorado 4 6
Utah 8 10
New York 12 14
对于特殊索引取值,首先通过切边或布尔型数组选取行 >>> data2[:2]
····one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
>>> data2[data2['three']>5]
····one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
另外一种方法是通过布尔型DataFrame进行索引 >>> data2<5
#通过布尔型进行判断符合条件的输出逻辑判断值True不符合条件的输出逻辑判断值False ····one two three four
Ohio True True True True
Colorado True False False False
Utah False False False False
New York False False False False
>>> data2[data2<5]
#选取符合条件的值,符合条件则输出其值,不符合条件则利用缺失值NaN代替 ····one two three four
Ohio 0.0 1.0 2.0 3.0
Colorado 4.0 NaN NaN NaN
Utah NaN NaN NaN NaN
New York NaN NaN NaN NaN
>>> data2[data2<5]=0
#选取符合条件的值并进行赋值 >>> data2
····one two three four
Ohio 0 0 0 0
Colorado 0 5 6 7
Utah 8 9 10 11
New York 12 13 14 15
同时也可通过 ix[] 这个取出索引的方法进行取值 >>> data2.ix['Colorado', ['two', 'three']]
#先取出横向索引,再取出纵向索引 two 5
three 6
Name: Colorado, dtype: int64
>>> data2.ix[data2.three > 5, :3]
#先进行值判断,再取出纵向索引的前三列 ····one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14
表5-6:DataFrame的索引选项
| 类型 | 说明 |
| obj [val] | 选取DataFrame的单个列或一组列。在一些特殊情况下会比较便利:布尔型数组(过滤行)、切片(行切片)、布尔型DataFrame(根据条件设置值) |
| obj.ix[val] | 选取DataFrame的单个行或一组行 |
| obj.ix[:, val] | 选取单个列或列子集 |
| obj.id[val1, val2] | 同时选取行和列 |
| reindex方法 | 将一个或多个轴匹配到新索引 |
| xs方法 | 根据标签选取单行或单列, 并返回一个Series |
| icol、irow方法 | 根据整数位置选取单列或单行,并返回一个Series |
| get_value、set_value方法 | 根据行标签和列标签选取单个值 |
4,算数运算和数据对齐
pandas对不同索引对象可进行算数运算
对象相加,如果存在不同索引对,结果索引就是该索引的并集 >>> s1=Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
>>> s2=Series([-2.1, 3.6, -1.5, 4, 3.1], index=['a', 'c', 'e', 'f', 'g'])
>>> s1
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
>>> s2
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
>>> s1+s2
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
数据对齐操作在不重叠的索引处会引入NA值
在算数方法中如何填充值 >>> df1=DataFrame(np.arange(12.).reshape((3, 4)), columns=list('abcd'))
>>> df2=DataFrame(np.arange(20.).reshape((4, 5)), columns=list('abcde'))
>>> df1
···a b c d
0 0.0 1.0 2.0 3.0
1 4.0 5.0 6.0 7.0
2 8.0 9.0 10.0 11.0
>>> df2
····a b c d e
0 0.0 1.0 2.0 3.0 4.0
1 5.0 6.0 7.0 8.0 9.0
2 10.0 11.0 12.0 13.0 14.0
3 15.0 16.0 17.0 18.0 19.0
DataFrame对象,在相加时,没有重叠的位置会产生NA值 >>> df1+df2
····a b c d e
0 0.0 2.0 4.0 6.0 NaN
1 9.0 11.0 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN
利用add方法,将df2当中的值添加到df1当中,传入df2以及一个fill_value参数
所以最终的结果是,df1+df2当中存在的值保留,而df1+df2当中的NA值则用df2填充 >>> df1.add(df2, fill_value=0)
···· a b c d e
0 0.0 2.0 4.0 6.0 4.0
1 9.0 11.0 13.0 15.0 9.0
2 18.0 20.0 22.0 24.0 14.0
3 15.0 16.0 17.0 18.0 19.0
结果是将df2中的值添加到df1当中后,再加入一个fill_value为0的值 >>> df1.add(df2, fill_value=10)
····a b c d e
0 0.0 2.0 4.0 6.0 14.0
1 9.0 11.0 13.0 15.0 19.0
2 18.0 20.0 22.0 24.0 24.0
3 25.0 26.0 27.0 28.0 29.0
结果是将df2中的值添加到df1当中后,再加入一个fill_value为10的值 >>> df1.reindex(columns=df2.columns, fill_value=0)
····a b c d e
0 0.0 1.0 2.0 3.0 0
1 4.0 5.0 6.0 7.0 0
2 8.0 9.0 10.0 11.0 0
表5-7:灵活的算术方法
| 方法 | 说明 |
| add | 用于加法(+)的方法 |
| sub | 用于减法(-)的方法 |
| div | 用于除法(/)的方法 |
| mul | 用于乘法(*)的方法 |
DataFrame和Series之间的运算 >>> arr=np.arange(12.).reshape((3, 4))
>>> arr
array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]])
>>> arr[0]
array([ 0., 1., 2., 3.])
>>> arr - arr[0]
array([[ 0., 0., 0., 0.], [ 4., 4., 4., 4.], [ 8., 8., 8., 8.]])
相当于array矩阵当中的每一行都与0,1,2,3相减
DataFrame当中的方法同样如此 >>> frame=DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>> series=frame.ix[0]
>>> frame
····b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
>>> series
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64
>>> frame - series
····b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0
5,函数应用和映射
Numpy的ufuncs(元素级数组方法)也可用于操作pandas对象 >>> frame=DataFrame(np.random.randn(4, 3),columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>> frame
····b d e
Utah 0.102222 -1.204168 0.517079
Ohio -1.738203 -0.514086 0.168409
Texas -0.410314 0.098605 -1.314011
Oregon 0.114196 -0.890712 -0.162612
>>> np.abs(frame)
····b d e
Utah 0.102222 1.204168 0.517079
Ohio 1.738203 0.514086 0.168409
Texas 0.410314 0.098605 1.314011
Oregon 0.114196 0.890712 0.162612
>>> frame=DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'), index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>> frame
····b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
>>> f=lambda x: x.max() - x.min()
#设定一个最大值减去最小值的函数 >>> f
<function <lambda> at 0x2af636d18398>
>>> frame.apply(f)
#将函数式应用到DataFrame对象上 b 9.0
d 9.0
e 9.0
dtype: float64
#计算每列得出的最大值 >>> frame.apply(f, axis=1)
Utah 2.0
Ohio 2.0
Texas 2.0
Oregon 2.0
dtype: float64
#计算每行得出的最大值
许多最为常见的数组统计功能都被实现成DataFrame的方法(如sum和mean),后面会进行介绍,因此无需使用apply方法。
传递给apply的函数还可以返回由多个值组成的Series >>> def f(x):
...····return Series([x.min(), x.max(), index=['min', 'max'])
>>> frame.apply(f)
····b d e
min 0.0 1.0 2.0
max 9.0 10.0 11.0
pandas中的applymap方法相当于函数map的作用,可实现各个浮点值ID格式化字符串 >>> format=lambda x: '%.2f' % x
>>> frame.applymap(format)
实现DataFrame中每个数字都保留两位小数 >>> frame['e'].map(format)
实现‘e’列数值保留两位小数
对于整个DataFrame的所有行和列,则可利用applymap的方法实现函数功能,而对于单个列则可用map的方法实现函数功能
6,序列和排名
可通过sort_index()的方法对行或者列索引进行排序 >>> frame=DataFrame(np.arange(8).reshape((2, 4)), index=['three', 'one'], columns=['d', 'a', 'b', 'c'])
····d a b c
three 0 1 2 3
one 4 5 6 7
>>> frame.sort_index()
#按照列索引进行排序 ····d a b c
one 4 5 6 7
three 0 1 2 3
>>> frame.sort_index(axis=1)
#按照行索引进行排序 ····d a b c
three 1 2 3 0
one 5 6 7 4
数据默认是按照升序排序的,不过ascending=False方法可以使数据按照降序排序 >>> frame.sort_index(axis=1, ascending=False)
····d c b a
three 0 3 2 1
one 4 7 6 5
任何缺失值默认都会被放倒Series的末尾
可以通过by的方法根据某列进行排序 >>> frame=DataFrame({'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
>>> frame
····a b
0 0 4
1 1 7
2 0 -3
3 1 2
>>> frame.sort_index(by='b')
#按照‘b’列进行排序 ···a b
2 0 -3
3 1 2
0 0 4
1 1 7
>>> frame.sort_index(by=['a', 'b'])
#分别对两列进行排序
7,带有重复值的轴索引
之前介绍的都是唯一轴标签(索引值),带有重复索引值的Series >>> obj=Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
>>> obj
a 0
a 1
b 2
b 3
c 4
dtype: int64
如果某个索引对应多个值,则返回一个Series;而对应单个值,则返回一个标量值。 >>> obj['a']
a 0
a 1
dtype: int64
>>> obj['c']
4
对DataFrame也有同样的结果