python pandas库的学习笔记二pandas的基本功能

时间:2022-07-06 01:24:14

1.重新索引

pandas对象的一个重要的方法就是reindex,作用是创建一个适应新索引的新对象。

>>> import numpy as np
>>> import pandas as pd
>>> from pandas import Series,DataFrame
>>> 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
dtype: float64
调用该Series的reindex将会根据新索引进行重排。如果某个索引值当前不存,就引入缺失值:
>>> obj1=obj.reindex(['a','b','c','d','e'])
>>> obj1
a -5.3
b 7.2
c 3.6
d 4.5
e NaN
dtype: float64
>>> obj.reindex(['a','b','c','d','e'],fill_value=0) #指定缺失值
a   -5.3
b    7.2
c    3.6
d    4.5
e    0.0
dtype: float64
对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可用达到此目的。例如:ffill可以实现向前值填充:
>>> obj3=Series(['blue','purple','yellow'],index=[0,2,4])
>>> obj3.reindex(range(6))
0 blue
1 NaN
2 purple
3 NaN
4 yellow
5 NaN
dtype: object
>>> obj3.reindex(range(6),method='ffill')
0 blue
1 blue
2 purple
3 purple
4 yellow
5 yellow
dtype: object
下面列出了可用的method选项。
参数                             说明
ffill或pad                      前向填充(或搬运)值
bfill或backfill                后向填充(或搬运)值

对于DataFrame,reindex可以修改(行)索引,列,或两个都修改。如果仅传入一个序列,则会重新索引行:

>>> frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['Ohio','Texas','California',]
... )
>>> frame
Ohio Texas California
a 0 1 2
c 3 4 5
d 6 7 8
>>> frame1=frame.reindex(['a','b','c','d'])
>>> frame1
Ohio Texas California
a 0.0 1.0 2.0
b NaN NaN NaN
c 3.0 4.0 5.0
d 6.0 7.0 8.0
利用columns关键字可以重新索引列:

>>> frame.reindex(columns=['Texas','Cali','Ohio'])
Texas Cali Ohio
a 1 NaN 0
c 4 NaN 3
d 7 NaN 6
利用ix的标签的索引功能,重新索引任务可以变得简洁:

>>> states=['Texas','Utah','California']
>>> index=['a','b','c','d']
>>> frame.ix[index,states]
Texas Utah California
a 1.0 NaN 2.0
b NaN NaN NaN
c 4.0 NaN 5.0
d 7.0 NaN 8.0
python pandas库的学习笔记二pandas的基本功能

2.删除指定轴上的项

使用drop方法删除某条轴上的一个或多个项,返回删除后的新对象。

>>> obj=Series(np.arange(5.),index=['a','b','c','d','e'])
>>> obj1=obj.drop('c')
>>> obj1
a 0.0
b 1.0
d 3.0
e 4.0
dtype: float64
对于DataFrame,通过指定axis,可以删除任意轴上的索引值:
>>> data=DataFrame(np.arange(16).reshape((4,4)),index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])
>>> data
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
>>> data.drop('two',axis=1)
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New York   12     14    15
>>> data.drop('Ohio',axis=0)
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

3.索引、选取和过滤

Series索引 (obj[...])的工作方式类似于NumPy数组的索引,只不过Series的索引值不只是整数。例:

>>> obj=Series(np.arange(4.),index=['a','b','c','d'])
>>> obj['b']
1.0
>>> obj[1] #或许可以理解为数组的下标吧
1.0
>>> obj[2:4]
c    2.0
d    3.0
dtype: float64
>>> obj[obj<2]
a    0.0
b    1.0
dtype: float64
利用标签的切片运算与普通的python切片运算不同,其末端是包含的(inclusive)
>>> obj['b':'c']
b 1.0
c 2.0
dtype: float64
设置值的方式如下:

>>> obj['b':'c']=5
>>> obj
a 0.0
b 5.0
c 5.0
d 3.0
dtype: float64
对DataFrame进行索引其实就是获取一个或多个列:
>>> data=DataFrame(np.arange(16).reshape((4,4)),
... index=['Ohio','Colorado','Utah','New York'],columns=['one','two','three','four'])
>>> data[['three','one']]
three one
Ohio 2 0
Colorado 6 4
Utah 10 8
New York 14 12
选取行可以通过切片或布尔数组进行

>>> data[:2]
one two three four
Ohio 0 1 2 3
Colorado 4 5 6 7
>>> data[data['three']>5]
one two three four
Colorado 4 5 6 7
Utah 8 9 10 11
New York 12 13 14 15

另一种用法使通过布尔型DataFrame进行索引:

>>> data<5
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
>>> data[data<5]=0
>>> data
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
这段代码使得DataFrame在语法上像ndarray
为了在DataFrame的行上进行标签索引,我们引入专门的索引字段ix。使得你通过numpy式的标记法以及轴标签的从DataFrame中选取行和列的子集。这是重现索引的简单手段:
>>> data
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
>>> data.ix['Colorado',['two','three']] #选取Colorado行,第two,three列
two 5
three 6
Name: Colorado, dtype: int32
>>> data.ix[['Colorado','Utah'],[3,0,1]] #选取Colorado行,第3,0,1列
four one two
Colorado 7 0 5
Utah 11 8 9
>>> data.ix[2] #选取第二行
one 8
two 9
three 10
four 11
Name: Utah, dtype: int32
>>> data.ix[data.three>5,:3] #选出three列大于5的行的前三列
one two three
Colorado 0 5 6
Utah 8 9 10
New York 12 13 14
由上可以看出对DataFrame选取和重排有许多种方法,下表列出了大部分的索引和重排方式:

python pandas库的学习笔记二pandas的基本功能
python pandas库的学习笔记二pandas的基本功能

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值。缺失值会在算术运算过程中传播。
对于DataFrame,对齐操作会同时发生在行和列上:

>>> df1=DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])
>>> df2=DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
>>> df1
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0
>>> df2
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
>>> df1+df2
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN

5.在算数方法中填充值

在不同索引的对象进行算术运算时,你可能希望当一个对象中某个轴标签在另一个对象张找不到时填充一个值:

>>> 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
>>> df1.add(df2,fill_value=0) #直接相加会产生NA值
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
由上可以看出,使用add方法和fill_value属性可以将没有重叠的位置填充上值。

类似的,对Series或DataFrame重新索引时,也可以指定一个填充值:

>>> df1.reindex(columns=df2.columns)
a b c d e
0 0.0 1.0 2.0 3.0 NaN
1 4.0 5.0 6.0 7.0 NaN
2 8.0 9.0 10.0 11.0 NaN
>>> 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
pandas中的算数方法如下:
方法                       说明
add                        用于加法(+)的方法
sub                        用于减法(-)的方法
div                         用于乘法(*)的方法
mul                        用于除法(/)的方法

6.DataFrame和Series之间的运算

跟NumPy数组一样,DataFrame和Series的=之间的算术运算也是有明确规定的。

下面来计算一个二维数组与其某行之间的差:

>>> arr=np.arange(12.).reshape((3,4))
>>> arr[0]
array([ 0., 1., 2., 3.])
>>> arr
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
>>> arr-arr[0]
array([[ 0., 0., 0., 0.],
[ 4., 4., 4., 4.],
[ 8., 8., 8., 8.]])
使用arr-arr[0]就相当于用arr的每一行去减去arr的第一行,这种运算叫做广播。
DataFrame和Series之间的运算差不多也是如此:

>>> 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
可以看到,和二维数组的运算是相似的。

如果你希望匹配行且在列上广播,则必须使用算术运算方法:

>>> series3=frame['d']
>>> 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
>>> series3
Utah 1.0
Ohio 4.0
Texas 7.0
Oregon 10.0
Name: d, dtype: float64
>>> frame.sub(series3,axis=0)
b d e
Utah -1.0 0.0 1.0
Ohio -1.0 0.0 1.0
Texas -1.0 0.0 1.0
Oregon -1.0 0.0 1.0
通过设置axis属性来达到在列上传播。

7.函数应用和映射

Numpy的ufuncs(元素级数组方法)也可以用于操作pandas对象:

>>> frame=DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
>>> frame
b d e
Utah 0.778854 -0.519687 -1.185915
Ohio -2.189872 -0.812754 0.099398
Texas 0.227312 -0.839251 -1.382977
Oregon 0.518163 -0.506687 1.110223
>>> np.abs(frame)
b d e
Utah 0.778854 0.519687 1.185915
Ohio 2.189872 0.812754 0.099398
Texas 0.227312 0.839251 1.382977
Oregon 0.518163 0.506687 1.110223
另一个常见的操作,将函数应用到由各列或行所形成的一维数组上。DataFrame的apply方法即可实现此功能:
>>> f=lambda x:x.max() - x.min() #
>>> frame.apply(f) #将函数作用于每一列
b 2.968725
d 0.332564
e 2.493200
dtype: float64
>>> frame.apply(f,axis=1) #将函数作用于每一行
Utah 1.964769
Ohio 2.289270
Texas 1.610289
Oregon 1.616909
dtype: float64
apply方法不会经常使用,因为常用的函数都已经被实现为DataFrame的方法(如sum和mean)
除标量外,传递给apply的函数还可以返回由多个值组成的Series

>>> def f(x):
... return Series([x.min(),x.max()],index=['min','max'])
...
>>> frame.apply(f)
b d e
min -2.189872 -0.839251 -1.382977
max 0.778854 -0.506687 1.110223
使用applymap可以将函数作用到每一个元素上:

>>> frame
b d e
Utah 0.778854 -0.519687 -1.185915
Ohio -2.189872 -0.812754 0.099398
Texas 0.227312 -0.839251 -1.382977
Oregon 0.518163 -0.506687 1.110223
>>> format=lambda x:'%.2f' %x
>>> frame.applymap(format)
b d e
Utah 0.78 -0.52 -1.19
Ohio -2.19 -0.81 0.10
Texas 0.23 -0.84 -1.38
Oregon 0.52 -0.51 1.11
而Series中作用于每一个元素的方法是map方法

>>> frame['e'].map(format)
Utah -1.19
Ohio 0.10
Texas -1.38
Oregon 1.11
Name: e, dtype: object

8.排序和排名

根据条件对数据集排序也是一种重要的内置运算。要对行或列索引进行排序(按字典顺序),可以使用sort_index方法,它将返回一个已经排序的新对象:

>>> obj=Series(range(4),index=['d','a','b','c'])
>>> obj.sort_index()
a 1
b 2
c 3
d 0
dtype: int64
而对于DataFrame,则可以根据任意一个轴上的索引进行排序:

>>> frame=DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
>>> frame.sort_index()
d a b c
one 4 5 6 7
three 0 1 2 3
>>> frame.sort_index(axis=1)
a b c d
three 1 2 3 0
one 5 6 7 4
数据默认是按升序排列的,但也可以降序排序:

>>> frame.sort_index(axis=1,ascending=False)
d c b a
three 0 3 2 1
one 4 7 6 5
在DataFrame上,你可能希望根据一个或多个列中的值进行排序。将一个或多个列的名字传递给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')
__main__:1: FutureWarning: by argument to sort_index is deprecated, pls use .sort_values(by=...)
a b
2 0 -3
3 1 2
0 0 4
1 1 7
要根据多个列进行排序,传入名称的列表即可。
排名(ranking)跟排序关系密切,且会增设一个排名值(从1开始,一直到数组中有效数据的数量),跟numpy.argsort产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。下面介绍Series和DataFrame的rank方法。默认下:rank是通过“为各组分配一个平均排名”的方式来破坏平级关系。
>>> obj=Series([7,-5,7,4,2,0,4])
>>> obj.rank()
0 6.5
1 1.0
2 6.5
3 4.5
4 3.0
5 2.0
6 4.5
dtype: float64
>>> obj
0 7
1 -5
2 7
3 4
4 2
5 0
6 4
dtype: int64
也可以根据值在原数据中出现的顺序给出排名:
>>> obj.rank(method='first')
0 6.0
1 1.0
2 7.0
3 4.0
4 3.0
5 2.0
6 5.0
dtype: float64
也可以按降序进行排名:
>>> obj.rank(ascending=False,method='max')
0 2.0
1 7.0
2 2.0
3 4.0
4 5.0
5 6.0
6 4.0
dtype: float64
DataFrame可以在行或列上计算排名:
>>> frame=DataFrame({'b':[4.3,7,-3,2],'a':[0,1,0,1],'c':[-2,5,8,-2.5]})
>>> frame
a b c
0 0 4.3 -2.0
1 1 7.0 5.0
2 0 -3.0 8.0
3 1 2.0 -2.5
>>> frame.rank(axis=1)
a b c
0 2.0 3.0 1.0
1 1.0 3.0 2.0
2 2.0 1.0 3.0
3 2.0 3.0 1.0
下面列出了method的可选项:

method                              说明
‘average’                           默认:在相等分组中,为各个值分配平均排‘’
‘min’                                   使用整个分组的最小排名
‘max’                                  使用整个分组的最大排名
‘first’                                   按值在原始数据中的出现顺序分配排名

9.带有重复值的索引

我们看看下面这个简单的带有重复索引值的Series:

>>> obj=Series(range(5),index=['a','a','b','b','c'])
>>> obj
a 0
a 1
b 2
b 3
c 4
dtype: int64
索引的is_unique属性可以告诉你他的值是否是唯一的:
>>> obj.index.is_unique
False
>>> frame.index.is_unique
True
对于重复的索引,数据选取的行为将会有些不同。如果某个索引对应的多个值,则返回一个Series,而对应单个值,则返回一个标量:
>>> obj['a']
a 0
a 1
dtype: int64
>>> obj['c']
4
对DataFrame的行进行索引时候也是如此:
>>> df=DataFrame(np.random.randn(4,3),index=['a','a','b','b'])
>>> df
0 1 2
a -1.932050 -1.271340 0.491396
a -0.105177 -0.169603 0.652282
b -0.111812 0.970321 -0.650144
b -0.706707 1.816764 -1.013891
>>> df.ix['b']
0 1 2
b -0.111812 0.970321 -0.650144
b -0.706707 1.816764 -1.013891

参考:

《利用python进行数据分析》