python:pandas(2),基本功能

时间:2022-03-07 02:22:12

利用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也有同样的结果