python学习(九)----pandas模块相关函数

pandas的基本数据结构

Series结构

类似于一维数组的对象,它由一组Numpy中各种数据类型的数据和一组标签组成。索引在左,值在右:

In [1]: import pandas as pd

In [2]: obj = pd.Series([1,2,3,4])

In [3]: obj
Out[3]: 
0    1
1    2
2    3
3    4
dtype: int64

注意:没有指定索引会自动创建0到N-1(N是数据长度)作为索引

Series的values和index属性可以获取数组表示形式和索引对象:

In [4]: obj.values
Out[4]: array([1, 2, 3, 4], dtype=int64)

In [5]: obj.index
Out[5]: RangeIndex(start=0, stop=4, step=1)

索引可以才创建时自己指定,然后通过一个或多个索引可取得对应值:

In [6]: obj = pd.Series([1,2,3,4],index=['a','b','c','d'])

In [7]: obj
Out[7]: 
a    1
b    2
c    3
d    4
dtype: int64

In [8]: obj.index
Out[8]: Index(['a', 'b', 'c', 'd'], dtype='object')

In [9]: obj['a']
Out[9]: 1

In [10]: obj[['c','d']]
Out[10]: 
c    3
d    4
dtype: int64

可以使用一下基本运算和numpy相关函数的数组运算,结果保留索引关系:

In [11]: import numpy as np

In [12]: obj*2
Out[12]: 
a    2
b    4
c    6
d    8
dtype: int64

In [13]: np.exp(obj)
Out[13]: 
a     2.718282
b     7.389056
c    20.085537
d    54.598150
dtype: float64

In [14]: obj[obj>1]
Out[14]: 
b    2
c    3
d    4
dtype: int64

Series可以看做字典,许多字典相关的函数都可用,也可直接通过字典创建Series:

In [16]: 'a' in obj
Out[16]: True

In [17]: 'e' in obj
Out[17]: False

In [18]: d = {'a':1,'b':2,'c':3}

In [19]: d
Out[19]: {'a': 1, 'b': 2, 'c': 3}

In [20]: obj = pd.Series(d)

In [21]: obj
Out[21]: 
a    1
b    2
c    3
dtype: int64

创建Series还可将键通过列表传入,会自动根据传入的字典查询有的值来生成Series,若字典中的键没有查到列表中的数据,则对应生成Series的键的值为NaN:

In [22]: alp = ['c','b','a','d']

In [23]: obj = pd.Series(d,index=alp)  #d={'a': 1, 'b': 2, 'c': 3},即前一个代码片段中的d

In [24]: obj
Out[24]: 
c    3.0
b    2.0
a    1.0
d    NaN
dtype: float64

panda的的isnull和notnull函数可以用来查询Series的值是否为NaN:

In [26]: pd.isnull(obj)
Out[26]: 
c    False
b    False
a    False
d     True
dtype: bool

In [27]: pd.notnull(obj)
Out[27]: 
c     True
b     True
a     True
d    False
dtype: bool

Series对象本身和其索引都有name属性,Series的索引可通过赋值修改:

In [28]: obj.name='test'

In [29]: obj.index.name='num'

In [30]: obj
Out[30]: 
num
c    3.0
b    2.0
a    1.0
d    NaN
Name: test, dtype: float64

In [31]: obj.index=['e','f','g','h']

In [32]: obj
Out[32]: 
e    3.0
f    2.0
g    1.0
h    NaN
Name: test, dtype: float64

DataFrame结构

DataFrame是表格形式的数据结构,它含有一个有序的列,每一列可以是不同的值类型。可以看做Series组成的字典公用同一个索引。即有行索引,又有列索引。构建DataFrame的方法较多,最常用的是直接传入一个由等长列表或Numpy数组组成的字典:

In [1]: data = {'name':['xd','xc','ch'],
   ...:         'birth':[1989,1988,1991],
   ...:         'amateur':['game','study','work']}
In [3]: frame = pd.DataFrame(data)

In [4]: frame
Out[4]: 
  amateur  birth name
0    game   1989   xd
1   study   1988   xc
2    work   1991   ch

又结果看出DataFrame会自动加上索引,且全部有序排列,当然可以自己指定排列顺序:

In [6]: pd.DataFrame(data,columns=['birth','name','amateur'])
Out[6]: 
   birth name amateur
0   1989   xd    game
1   1988   xc   study
2   1991   ch    work

可以自己定义索引,如果顺序列表中找不到,则会产生NaN:

In [7]: pd.DataFrame(data,columns=['birth','name','amateur','gender'],index=['a','b','c'])
Out[7]: 
   birth name amateur gender
a   1989   xd    game    NaN
b   1988   xc   study    NaN
c   1991   ch    work    NaN

通过字典标记,或属性方式,可得到对应列的Series数据:

In [8]: frame['name']
Out[8]: 
0    xd
1    xc
2    ch
Name: name, dtype: object

In [9]: frame.birth
Out[9]: 
0    1989
1    1988
2    1991
Name: birth, dtype: int64

In [10]: type(frame.birth)
Out[10]: pandas.core.series.Series

通过ix方法可以索引一行的字段:

In [13]: frame.ix[1]
Out[13]: 
amateur    study
birth       1988
name          xc
Name: 1, dtype: object

可通过赋值的方式加上新的列,若通过Series结构赋值,则可精确匹配DataFrame的索引:

In [14]: frame
Out[14]: 
  amateur  birth name
0    game   1989   xd
1   study   1988   xc
2    work   1991   ch

In [15]: frame['age'] = 24

In [16]: frame
Out[16]: 
  amateur  birth name  age
0    game   1989   xd   24
1   study   1988   xc   24
2    work   1991   ch   24

In [17]: import numpy as np
In [22]: frame['age'] = np.arange(25.,28.)

In [23]: frame
Out[23]: 
  amateur  birth name   age
0    game   1989   xd  25.0
1   study   1988   xc  26.0
2    work   1991   ch  27.0

In [24]: gen = pd.Series(['M','F'],index=[2,1])

In [25]: frame['gender']=gen

In [26]: frame
Out[26]: 
  amateur  birth name   age gender
0    game   1989   xd  25.0    NaN
1   study   1988   xc  26.0      F
2    work   1991   ch  27.0      M

del关键字可以删除列:

In [27]: del frame['age']

In [28]: frame
Out[28]: 
  amateur  birth name gender
0    game   1989   xd    NaN
1   study   1988   xc      F
2    work   1991   ch      M

注意:通过索引得到的列是对应数据的视图,因此对返回的Series数据的修改会反应到DataFrame数据上,通过Series的copy方法可以显式的复制对应数据。

另一种构建DataFrame的方式是嵌套字典,外层字典键作为列索引,内存字典键作为行索引,结果也可转置:

In [30]: dic = {'MM':{'outfile':'beautiful',2017:6.6},'GG':{'outfile':'handsome',2017:8.8}}
In [32]: frame = pd.DataFrame(dic)

In [33]: frame
Out[33]: 
               GG         MM
outfile  handsome  beautiful
2017          8.8        6.6

In [34]: frame.T
Out[34]: 
      outfile 2017
GG   handsome  8.8
MM  beautiful  6.6

下表列出DataFrame可接受的数据:

类型说明
二维ndarry数据矩阵,还可以传入行标和列标
由数组、列表、元组组成的字典每个序列会变成DataFrame的一列。所有序列长度必须相同
Numpy的结构化/记录数组类似于“由数组组成的字典”
由Series组成的字典每个Series会成为一列。如果没有显示指定索引,则各Series的索引会被合并成结果的行索引
由字典组成的字典各内层字典会成为一列。键会被合并成结果的行索引,跟“由Series组成的字典”情况一样
字典或Series的列表各项将成为DataFrame的一行。字典键或Series索引的并集将会成为DataFrame的列标
由列表或元组组成的列表类似于“二维ndarry”
另一个DataFrame将会使用该索引,除非自己显示指定
Numpy的MaskedArray类似于“二维ndarry”,只是掩码值在结果DataFrame会变为NaN缺失值

以上生成时都可自己设置DataFrame的index和columns的name属性,这时会显示出来:

In [39]: frame.index.name = 'character'

In [40]: frame.columns.name = 'people'

In [41]: frame
Out[41]: 
people           GG         MM
character                     
outfile    handsome  beautiful
2017            8.8        6.6

跟Series数据类似,通过values属性可以返回二维ndarry形式的数据:

In [42]: frame.values
Out[42]: 
array([['handsome', 'beautiful'],
       [8.8, 6.6]], dtype=object)

Index索引对象

pandas的索引对象负责管理轴标签和其他元数据,构建Series或DataFrame时,所用的任何数组或其他序列的标签都会转换成一个Index:

In [44]: obj = pd.Series(range(3),index=['a','b','c'])

In [45]: index = obj.index

In [46]: index
Out[46]: Index(['a', 'b', 'c'], dtype='object')

In [47]: index[1:]
Out[47]: Index(['b', 'c'], dtype='object')

注意:index是不可修改的。这样才能使得Index对象在多个数据结构之间安全共享。

In [50]: index = pd.Index(np.arange(3))
In [53]: obj = pd.Series([1.1,2.2,3.3],index = index)

In [54]: index
Out[54]: Int64Index([0, 1, 2], dtype='int64')

In [55]: index is obj.index
Out[55]: True

下面列出pandas内置的Index类:

说明
Index最泛化的Index对象,将轴标签表示为一个由Python对象组成的Numpy数组
Int64Index针对整数的特殊Index
MultiIndex“层次化”索引对象,表示单个轴上的多层索引。可以看做由元组组成的数组
DatetimeIndex存储纳秒级时间戳(用Numpy的datetime64类型表示)
PeriodIndex针对Period数据(时间间隔)的特殊Index

索引还有一些方法和属性,用于设置逻辑并回答有关该索引所包含的数据的常见问题,下表列出这些函数:

方法说明
append连接另一个Index对象,产生一个新的Index
difference计算差集,得到一个Index
intersection计算交集
union计算并集
isin计算一个指示各值是否都包含在参数集中的布尔型数组
delete删除索引i处的元素,并得到新的Index
drop删除传入值,并得到新的Index
insert将索引插入到i处,得到新的Index
is_monotonic当各元素均大于等于前一个元素时,返回True
is_unique当Index没有重复值是,返回True
unique计算Index中唯一值的数组

例如:

In [54]: index
Out[54]: Int64Index([0, 1, 2], dtype='int64')

In [56]: index2 = pd.Index(range(6))
In [57]: index2
Out[57]: RangeIndex(start=0, stop=6, step=1)

In [58]: index2.difference(index)
Out[58]: Int64Index([3, 4, 5], dtype='int64')

In [59]: index2.drop(4)
Out[59]: Int64Index([0, 1, 2, 3, 5], dtype='int64')

In [61]: index2.insert(2,2)
Out[61]: Int64Index([0, 1, 2, 2, 3, 4, 5], dtype='int64')

In [63]: index2.is_monotonic
Out[63]: True

In [64]: index2.is_unique
Out[64]: True

In [66]: index2.unique()
Out[66]: Int64Index([0, 1, 2, 3, 4, 5], dtype='int64')

基本功能

下面介绍操作Series和DataFrame数据的基本手段

重新索引

pandas对象的reindex方法用来创建一个适应新索引的新对象。比如调用Series的reindex方法可以根据新索引重新排序。如果某个索引不存在则引入NaN,当然可以通过参数fill_value改变不存在该索引时的填充值:

In [67]: obj
Out[67]: 
0    1.1
1    2.2
2    3.3
dtype: float64

In [68]: obj.reindex([1,2,0])
Out[68]: 
1    2.2
2    3.3
0    1.1
dtype: float64

In [69]: obj  #reindex函数不改变本身,只是生成一个新的
Out[69]: 
0    1.1
1    2.2
2    3.3
dtype: float64

In [70]: obj.reindex([2,1,0,5],fill_value=10)
Out[70]: 
2     3.3
1     2.2
0     1.1
5    10.0
dtype: float64

重新索引时还可通过method选项进行向前或向后差值,可设置结果表格:

参数说明
ffill或pad前向填充(或搬运)值
bfill或backfill后向填充(或搬运)值

例如:

In [72]: obj = pd.Series(['a','b','c'],index=[2,5,8])

In [73]: obj.reindex(range(8),method='pad')
Out[73]: 
0    NaN
1    NaN
2      a
3      a
4      a
5      b
6      b
7      b
dtype: object

In [74]: obj
Out[74]: 
2    a
5    b
8    c
dtype: object

对应DataFrame的reindex函数可修改行、列索引,或同时都修改。仅仅传入序列会重新索引行:

In [76]: frame = pd.DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['o','p','q'])

In [77]: frame
Out[77]: 
   o  p  q
a  0  1  2
b  3  4  5
c  6  7  8

In [78]: frame.reindex(['b','c','d','e'])
Out[78]: 
     o    p    q
b  3.0  4.0  5.0
c  6.0  7.0  8.0
d  NaN  NaN  NaN
e  NaN  NaN  NaN

显示传入index代表重新索引行,columns代表重新索引列,当然可以混合使用这两个参数:

In [5]: frame.reindex(index=['c','b','a'],columns=['q','p','o','j'])
Out[5]: 
     q    p    o   j
c  8.0  7.0  6.0 NaN
b  5.0  4.0  3.0 NaN
a  2.0  1.0  0.0 NaN

下面列出reindex函数各个参数的说明表格:

参数说明
index用作索引的新序列,可以是Index实例,也可是其他序列的Python数据结构。
method差值的方式,具体见上一个表格
fill_value在重新索引时,需要引入缺失值时使用的代替值
limit前向或后向填充时最大填充量
level在MultiIndex的指定级别上匹配简单索引,否则选取其子集
copy默认为True,无论如何都复制;如果为Flase,则新旧相等则不复制

丢弃轴上值

使用drop函数可返回一个指定轴上删除后的新数据对象,默认是0轴,如果要删除其他轴上的数据,需要显示指定axis数:

In [10]: frame
Out[10]: 
   o  p  q
a  0  1  2
b  3  4  5
c  6  7  8

In [11]: frame.drop(['b','c'])
Out[11]: 
   o  p  q
a  0  1  2

In [12]: frame.drop('a')
Out[12]: 
   o  p  q
b  3  4  5
c  6  7  8

In [13]: frame.drop('o',axis=1)
Out[13]: 
   p  q
a  1  2
b  4  5
c  7  8

索引数据

DataFrame索引选项表格:

类型说明
obj[val]选取DataFrame的单个列或一组列。在一些特殊情况下会比较便利:布尔型数组(过滤行)、切片(切片行)、布尔型DataFrame(根据条件设置值)
obj.ix/loc[val]选取DataFrame的单个行或一组行(loc传入的是标签)
obj.ix/loc[:,val]选取单个列或列子集(loc传入的是标签)
obj.ix/loc[val1,val2]同时选取行和列(loc传入的是标签)
reindex方法将一个或多个轴匹配到新索引
xs方法根据标签选取单行或单列,并返回一个Series数据
icol、irow方法根据整数位置选取单列或单行,并返回一个Series数据
get_value、set_value方法根据行标签或列标签选取单个值

例如:

In [31]: frame
Out[31]: 
   o  p  q
a  0  1  2
b  3  4  5
c  6  7  8

In [32]: frame['o']
Out[32]: 
a    0
b    3
c    6
Name: o, dtype: int32

In [33]: frame[frame['o']>0]
Out[33]: 
   o  p  q
b  3  4  5
c  6  7  8

In [34]: frame[:2]
Out[34]: 
   o  p  q
a  0  1  2
b  3  4  5

In [47]: frame.ix[0]
Out[47]: 
o    0
p    1
q    2
Name: a, dtype: int32

In [48]: frame.ix[:,0]
Out[48]: 
a    0
b    3
c    6
Name: o, dtype: int32

数据结构的简单计算

DataFrame数据进行相加时,不重叠的地方产生NaN值,可以通过其本身的add方法传入相加的值,和fill_value参数:

In [66]: frame1 = pd.DataFrame(np.arange(6.).reshape((2,3)),columns=['a','b','c'])
In [69]: frame2 = pd.DataFrame(np.arange(12.).reshape((3,4)),columns=list('abcd'))

In [70]: frame1
Out[70]: 
     a    b    c
0  0.0  1.0  2.0
1  3.0  4.0  5.0

In [71]: frame2
Out[71]: 
     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

In [72]: frame1+frame2
Out[72]: 
     a    b     c   d
0  0.0  2.0   4.0 NaN
1  7.0  9.0  11.0 NaN
2  NaN  NaN   NaN NaN

In [73]: frame1.add(frame2,fill_value=0.)
Out[73]: 
     a    b     c     d
0  0.0  2.0   4.0   3.0
1  7.0  9.0  11.0   7.0
2  8.0  9.0  10.0  11.0

In [75]: frame2-frame1.ix[0]
Out[75]: 
     a    b    c   d
0  0.0  0.0  0.0 NaN
1  4.0  4.0  4.0 NaN
2  8.0  8.0  8.0 NaN

函数的应用

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

In [79]: np.sqrt(frame)
Out[79]: 
          o         p         q
a  0.000000  1.000000  1.414214
b  1.732051  2.000000  2.236068
c  2.449490  2.645751  2.828427

还可以直接将函数应用到DataFrame的apply方法上:

In [81]: frame.apply(lambda x:x.max()-x.min(),axis=1)
Out[81]: 
a    2
b    2
c    2
dtype: int64

也可使用应用到每个元素的方法applymap:

In [83]: frame.applymap(lambda x:'%.2f'%x)
Out[83]: 
      o     p     q
a  0.00  1.00  2.00
b  3.00  4.00  5.00
c  6.00  7.00  8.00

排序

索引排序也是对数据的常用操作,使用的函数是sort_index,该函数可以指定axis参数表示行索引排序或列索引排序,指定ascending指定升序或降序排序。对值排序可使用sort_values函数,其中指定by代表对一列或多列的进行排序:

In [85]: frame.sort_index(axis=1,ascending=False)
Out[85]: 
   q  p  o
a  2  1  0
b  5  4  3
c  8  7  6

In [88]: frame.sort_values(by=['p','o'],ascending=False)
Out[88]: 
   o  p  q
c  6  7  8
b  3  4  5
a  0  1  2

排名

排名使用rank方法,其参数method对应的选项意思为:

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

例如:

obj = pd.Series([-3,2,7,3,3])

obj.rank()
Out[13]: 
0    1.0
1    2.0
2    5.0
3    3.5
4    3.5
dtype: float64

obj = pd.Series([-3,2,7,3,3,3])

obj.rank()
Out[15]: 
0    1.0
1    2.0
2    6.0
3    4.0
4    4.0
5    4.0
dtype: float64

显然,如果出现被排名的出现相同的结果,那么平均方法就按照占有的排名数字的平均数给出排名的序列值。

计算描述统计的方法

下面列出描述和汇总统计的常用方法:

方法说明
count非NA值的数量
describe针对Series或各DataFrame列计算汇总统计
count非NA值的数量
describe针对Series和DataFrame列计算汇总统计
min、max计算最小值和最大值
argmin、argmax计算能够获取到最小值、最大值的索引位置(整数)
idxmin、idxmax计算能够获取到最小值、最大值的索引值
quantile计算样本的分位数(0到1)
sum值的总和
mean值的平均数
median值的算术中位数(50%分位数)
mad根据平均值计算平均绝对离差
var样本值的方差
std样本值的标准差
skew样本值的偏度(三阶矩)
kurt样本值的峰度(四阶矩)
cumsum样本值的累计和
cummin、cummax样本值的累计最大值和累计最小值
cumprod样本值的累计积
diff计算一阶差分(对时间序列很有用)
pct_change计算百分数变化

方法的常用选项表格:

选项说明
axisDataFrame的行用0,列用1
skipna排除缺失值,默认值为True
level如果轴是层次化索引的(即MultiIndex),则根据level分组约简

例如:

In [23]: frame = pd.DataFrame([[3.4,np.nan],[4.5,5.6],[np.nan,np.nan],[1.1,4.4]],index=['a','b','c','d'],columns=['one','two'])

In [24]: frame
Out[24]: 
   one  two
a  3.4  NaN
b  4.5  5.6
c  NaN  NaN
d  1.1  4.4

In [25]: frame.sum()
Out[25]: 
one     9.0
two    10.0
dtype: float64

In [26]: frame.sum(axis=1)
Out[26]: 
a     3.4
b    10.1
c     0.0
d     5.5
dtype: float64

In [27]: frame.mean()
Out[27]: 
one    3.0
two    5.0
dtype: float64

In [29]: frame.cumsum()
Out[29]: 
   one   two
a  3.4   NaN
b  7.9   5.6
c  NaN   NaN
d  9.0  10.0

一些其他常用方法

方法名方法作用
corr计算相关系数
cov计算协方差
unique计算Series中唯一值的数组,按发现的顺序返回
value_count返回一个Sereies,其索引为唯一值,其值为各个值出现的频率,按计数值降序排列
isin计算一个表示“Series各值是否包含于传入的值序列中”的布尔型数组

回忆:

协方差公式: C o v ( X , Y ) = E [ ( X − m 1 ) ( Y − m 2 ) ] Cov(X,Y)=E[(X-m_1)(Y-m_2)] Cov(X,Y)=E[(Xm1)(Ym2)]理解:X的方差是 ( X − m 1 ) (X-m_1) (Xm1) ( X − m 1 ) (X-m_1) (Xm1)的乘积的期望,如今把一个 ( X − m 1 ) (X-m_1) (Xm1)换为 ( Y − m 2 ) (Y-m_2) (Ym2),其形式接近方差,又有X,Y的参与,由此得出协方差的名称。可以看出与次序无关,即: C o v ( X , Y ) = C o v ( Y , X ) Cov(X,Y)=Cov(Y,X) Cov(X,Y)=Cov(Y,X)若X,Y独立,则 C o v ( X , Y ) = 0 Cov(X,Y)=0 Cov(X,Y)=0


相关系数公式: C o r r ( X , Y ) = C o v ( X , Y ) / ( σ 1 σ 2 ) Corr(X,Y)=Cov(X,Y)/(\sigma_1\sigma_2) Corr(X,Y)=Cov(X,Y)/(σ1σ2)

处理区缺失值的方法

方法名方法作用
dropa根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度
fillna用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值NA,该对象的类型与源类型一样
notnullisnull的否定式

其中fillna函数的参数说明表格如下:

参数说明
value用于填充缺失值的标量值或字典对象
method插值方式。如果函数调用时未指定其他参数的话,默认为“ffill”
axis待填充的轴,默认axis=0
inplace修改调用者对象而不产生副本
limit(对于前向和后向填充)可以连续填充的最大数量
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值