Python数据处理手册

关键词: Python

  • Python数据处理手册
  • 1引言
  • 2Numpy基础数组和矢量计算
  • 1 一种多维数组对象ndarray
  • 2 运算函数
  • 3 利用数组进行数据处理
  • 4 数组的文件输入输出
  • 5 线性代数
  • 6 随机数生成
  • pandas
  • 1 Series
  • 2 DataFrame
  • 3 索引对象
  • 4 重新索引
  • 5 丢弃指定轴上的项
  • 6 索引选取和过滤
  • 7 算术运算和数据对齐
  • 8 DataFrame和Series之间的运算
  • 9 函数应用和映射
  • 10 排序和排名
  • 11 带有重复值的轴索引
  • 12 汇总和计算描述统计
  • 13 相关系数与协方差
  • 14 唯一值值计数以及成员资格
  • 15 处理缺失数据

1、引言

numpy和pandas的常用函数及方法。

2、Numpy基础:数组和矢量计算

2.1 一种多维数组对象ndarray

2.2 运算函数

  • 通用函数(即ufunc)是一种对ndarray中的数据执行元素级运算的函数。
#数组开方运算函数
>>>arr = np.arange(4)
>>>arr
array([0, 1, 2, 3])
>>>np.sqrt(arr)
array([ 0.        ,  1.        ,  1.41421356,  1.73205081])
  • np.modf() #分别显示浮点整数的小数部分和整数部分
>>>np.modf(np.sqrt(arr))
(array([ 0.        ,  0.        ,  0.41421356,  0.73205081]),
 array([ 0.,  1.,  1.,  1.]))
  • 一元ufunc
•  np.abs()、np.fabs() #计算整数、浮点数或复数的绝对值。对于非复数值,可以使用更快的fabs 
 np.sqrt() #计算各元素的平方根,相当于arr ** 0.5 
 np.square() #计算各元素的平方。相当于arr ** 2 
 np.exp() #计算各元素的指数 
 np.log()、np.log10()、np.log2()、np.log1p() #分别为自然对数(e)、底数为10、底数为2、log(1+x) 
 np.sign() #计算各元素的正负号:1(正数)、0(零)、-1(负数) 
 np.ceil() #计算各元素的ceiling值,即大于等于该值的最小整数 
 np.floor() #计算各元素的floor值,即小于等于该值的最大整数 
 np.rint() #将各元素值四舍五入到最接近的整数,保留dtype 
 np.modf() #将数组的小数和整数部分以两个独立数组的形式返回 
 np.isnan() #返回一个表示“哪些值是NaN(这不是一个数字)”的布尔数组 
 np.isfinite()、np.isinf() #分布返回一个表示“哪些元素是有穷的(非inf,非NaN)”或“哪些元素是无穷的”的布尔型数组 
 np.cos()、np.cosh()、np.sin()、np.sinh() #普通型和双曲型三角函数 
 np.tan()、np.tanh()、np.arcos()、np.arccosh()、np.arcsin()、np.arcsinh()、np.arctan()、np.arctanh() #反三角函数 
 np.logical_not() #计算各元素not x 的真值。相当于-arr
  • 二元ufunc
•  np.add(arr1,arr2) #将数组中对应的元素相加 
 np.subtract() #从第一个数组中减去第二个数组中的元素 
 np.multiply() #数组对应元素相乘 
 np.divide()、np.floor_divide() #除法或向下圆整除法(丢弃余数) 
 np.power() #对第一个数组中的元素A,根据第二个数组中的相应元素B,计算AB” role=”presentation” style=”position: relative;”>ABAB 
 np.maximum()、np.fmax() #元素级的最大值计算。fmax将忽略NaN 
 np.minimum()、np.fmin() #元素级的最小值计算。fmin将忽略NaN 
 np.mod() #元素级的求模运算(除法的余数) 
 np.copysign() #将第二个数组中的值的符合复制给第一个数组中的值 
 np.greater()、np.greater_equal()、np.less()、np.less_equal()、np.logical_and()、np.logical_or()、np.logical_xor() #执行元素级的比较运算,最终产生布尔型数组,相当于>、>=、<、<=、==、!=

2.3 利用数组进行数据处理

  • np.where() #是三元表达式x if condition else y的矢量化版本。
#当c为True,取x;当c为False,取y
>>>x = np.array([1.1,1.2,1.3, 1.4, 1.5])
>>>y = np.array([2.1, 2.2, 2.3, 2.4, 2.5])
>>>c = np.array([True, False, True, True, False])
>>>result = np.where(c, x, y)
array([1.1, 2.2, 1.3, 1.4, 2.5])

where通常用于根据另一个数组而产生一个新的数组。
传递给where的数组大小可以不相等,甚至可以是标量值。

  • 数学和统计方法
    获取正态分布的函数:np.random.randn(行数,列数),参数只有一个时,生成的是一维数组。
  • 基本数组统计方法
>>>arr = np.arange(9).reshape((3,3))
>>>arr
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
arr.sum() #对数组中全部或某轴向的元素求和。零长度的数组的sum为0 
 arr.mean() #算术平均数。零长度的数组的mean为NaN 
 arr.std()、arr.var() #分别为标准差和方差,自由度可调(默认为n) 
 arr.min()、arr.max() #最大值和最小值 
 arr.argmin()、arr.argmax() #分别为最大和最小元素的索引 
 arr.cumsum() #所有元素的累积和 
 arr.cumprod() #所有元素的累积积

在上面这些方法中,布尔值会被强制转换为1(True)和0(False)

>>>(arr > 0).sum() #正数的数量
>>>8

arr.any()、arr.all() #它们对布尔数组非常有用。any用于测试数组中是否存在一个或多个True,而all则检查数组中所有值是否都是True

>>>arr = np.array([False, False, True, False])
>>>arr.any()
True
>>>arr.all()
False
  • 排序
    arr.sort() #同Python内置的列表类型一样
  • 唯一化及其他的集合逻辑
    np.unique(数组名) #用于找出数组中的唯一值并返回已排序的结果
>>>names = np.array(['Bob','Joe', 'Will', 'Bob','Joe', 'Will', 'Joe])
>>>np.unique(names)
array(['Bob','Joe','Will'])

#该方法和set有些类似

数组的集合运算

np.unique(x) #计算x中的唯一元素,并返回有序结果 
 np.intersect1d(x,y) #计算x和y中的公共元素,并返回有序结果 
 np.union1d(x,y) #计算x和y的并集,并返回有序结果 
 np.in1d(x,y) #得到一个表示“x的元素是否包含于y”的布尔型数组 
 np.setdiff1d(x,y) #集合的差,即元素在x中且不在y中 
 np.setxor1d(x,y) #集合的对称差,即存在于一个数组中,但不同时存在于两个数组中的元素

2.4 数组的文件输入输出

  • Numpy能够读写磁盘上的文本数据、二进制数据。
  • 将数组以二进制格式保存到磁盘。
  • np.save()、np.load()是读写磁盘数组数据的两个主要函数。默认情况下,数组以未压缩的原始二进制格式保存在扩展名为.npy的文件中。
>>>arr = np.arange(10)
>>>np.save('an_array', arr)  #将arr保存到磁盘。如果文件路径末尾没有扩展名.npy,则该扩展名会被自动加上
>>>np.load('an_array.npy')  #读取磁盘数组
  • np.savez() #可以将多个数组保存到一个压缩文件中,将数组以关键字参数的形式传入即可。
>>>np.savez('array.npz', a = arr, b = arr)
>>>m = np.load('array.npz')
>>>m['a']
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
  • 存取文本文件
    从文件中加载文本是一个非常标准的任务。python中的文件读写函数格式很容易将新手搞晕,所以主要介绍pandas中的read_csvread_table。有时也需要np.loadtxtnp.genfromtxt将数据加载到普通的NumPy数组中。
>>>arr = np.loadtxt('array.txt', delimiter = ',')

#np.savetxt() 执行的是相反的操作:将数组写到以某种分隔符隔开的文本文件中。genfromtxt跟loadtxt差不多,只不过它面向的是结构化数组和缺失数据处理。

2.5 线性代数

NumPy中的矩阵乘法函数:np.dot(x,y)

>>>a = np.random.randn(3,3)
>>>b = np.random.randn(3,4)
>>>a
array([[ 0.79424789,  2.13225629],
       [ 0.56193264,  0.28040479]])
>>>b
array([[ 2.77264694, -0.76840806, -0.92406786],
       [ 0.99918608,  0.33742714,  1.04551225]])
>>>np.dot(a,b)
array([[ 4.33268977,  0.10917466,  1.49536114],
       [ 1.83821738, -0.33717739, -0.22609725]])
  • 常用的numpy.linalg函数
• np.diag(arr) #以一维数组的形式返回方阵的对角线(或非对角线)元素,或将一维数组转换为方阵(非对角线元素为0) 
np.dot(x,y) #矩阵乘法 
np.trace() #计算对角线元素的和 
np.linalg.det() #计算矩阵行列式 
np.linalg.eig() #计算方阵的本特征和本特征向量 
np.linalg.inv() #计算方阵的逆 
np.linalg.pinv() #计算方阵的Moore-Penrose伪逆 
np.linalg.qr() #计算QR分解 
np.linalg.svd() #计算奇异值分解 
np.linalg.solve(A,b) #解线性方程组Ax=b,其中A为一个方阵 
np.linalg.lstsq() #计算Ax=b的最小二乘解

2.6 随机数生成

numpy.random模块对python内置的random进行了补充,增加了一些用于高效生成多种概率分布的样本值的函数。

>>>a = np.random.normal((size=(3,3)) 
#用size=(行数,列数),生成数组,不用size,仅生成一个值,其他函数也是如此
>>>a
array([[-0.96685449,  0.08163984, -0.22994784],
       [-0.64561687,  0.77092965,  0.69356818],
       [ 0.76825463, -1.68469753,  2.07854679]])
  • numpy.random函数
• np.random.seed() #确定随机数生成器的种子 
np.random.permutation() #返回一个序列的随机排列或返回一个随机排列的范围 
np.random.shuffle() #对一个序列就地随机排列 
np.random.rand() #产生均匀分布的样本值 
np.random.randint() #从给定的上下限范围内随机选取整数 
np.random.randn() #产生正态分布(平均值为0,标准差为1)的样本值,类似于Matlab接口 
np.random.binomial() #产生二项分布的样本值 
np.random.normal() #产生正态(高斯)分布的样本值 
np.random.beta() #产生Beta分布的样本值 
np.random.chisquare() #产生卡方分布的样本值 
np.random.gamma() #产生Gamma分布的样本值 
np.random.uniform() #产生在(0,1)中均匀分布的样本值

3 pandas

pandas是基于NumPy构建的,让以NumPy为中心的应用变得更加简单。
引入pandas方式:

from pandas import Series, DataFrame

import pandas as pd

3.1 Series

  • Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。
  • Series:索引在左,值在右边
    仅由一组数据即可产生最简单的Series:
>>>obj = Series([4,7,-5,3])
>>>obj
0  4
1  7
2  -5
3  3
#通过values、index指定属性获取其数组表示形式和索引对象
>>>obj.values
array([4,7,-5,3])
>>>obj.index
Int64Index([0,1,2,3])
>>>obj2 = Series([4,5,6,7],index = ['d','b','a','c'])  #添加索引值, 索引可以通过赋值的方式就地修改obj2.index={}
>>>obj2
d    4
b    5
a    6
c    7
dtype: int64
>>>obj2['a']  #索引
6
>>>obj2[['a','b']]  #索引
a  6
b  5
  • Series同样可以使用标量乘法、数学运算函数
  • 如果数据别存放在一个python字典中,也可以直接通过这个字典来创建Series。
>>>dict = {'a':2,'b':3,'c':4}
>>>obj3 = Series(dict)
>>>obj3
a  2
b  3
c  4

如果只传入一个字典,则结果Series中的索引就是原字典的键。

  • pd.isnull()、pd.notnull()可用于检测缺失数据
>>>pd.isnull(obj3) #也可以用obj3.isnull()
a  False
b  False
c  False
>>>pd.notnull(obj3)
a  True
b  True
c  True

3.2 DataFrame

  • DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)
>>>data = {'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}  #字典
>>>frame = DataFrame(data)
>>>frame
   pop   state  year
0  1.5    Ohio  2000
1  1.7    Ohio  2001
2  3.6    Ohio  2002
3  2.4  Nevada  2001
4  2.9  Nevada  2002
#结果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列

#如果指定了列序列,则按指定的列排列(如果传入的列找不到,就会产生NaN值)
>>>DataFrame(data, columns = ['year','state','pop']
   year   state  pop
0  2000    Ohio  1.5
1  2001    Ohio  1.7
2  2002    Ohio  3.6
3  2001  Nevada  2.4
4  2002  Nevada  2.9

#索引(DataFrame添加指定索引的方式同Series相同,参考3.1)
>>>frame.year
0    2000
1    2001
2    2002
3    2001
4    2002
Name: year, dtype: int64

#按行索引frame.ix[索引名或行列]
>>>frame.ix[2]
pop       3.6
state    Ohio
year     2002
Name: 2, dtype: object

#如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来
>>>frame.index.name = 'xuhao';frame.columns.name = 'state'

state  pop   state  year
xuhao                   
0      1.5    Ohio  2000
1      1.7    Ohio  2001
2      3.6    Ohio  2002
3      2.4  Nevada  2001
4      2.9  Nevada  2002

列可以通过赋值的方式进行修改。
将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都讲被填上缺失值。

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

3.3 索引对象

  • index()
>>>obj = Series(range(3), index = ['a','b','c'])
>>>index = obj.index
Index([u'a', u'b', u'c'], dtype='object')
  • pandas中主要的index对象
• index() #最泛化的index对象,将轴标签标示为一个由Python对象组成的NumPy数组 
int64index() #针对整数的特殊index 
Multiindex() #“层次化”索引对象,标示单个轴上的多层索引。可以看做由元组组成的数组 
datetimeindex() #存储纳秒级时间戳(用NumPy的datetime64类型标示) 
periodindex() #针对period数据(时间间隔)的特殊index
  • index的方法和属性
• append() #连接另一个index对象,产生一个新的index 
diff() #计算差集,并得到一个index 
intersection() #计算交集 
union() #计算并集 
isin() #计算一个指示各值是否都包含在参数集合中的布尔型数组 
delete() #删除索引i处的元素,并得到新的index 
drop() #删除传入的值,并得到新的index 
insert() #将元素插入到索引i处,并得到新的index 
is_moontonic() #当各元素均大于等于前一个元素时,返回True 
is_quique() #当index没有重复值时,返回True 
unique() #计算index中唯一值的数组

3.4 重新索引

>>>obj = Series(range(3), index = ['a','b','c'])
>>>obj2 = obj.reindex(['a','b','c','d'])  #调用该Series的reindex将会根据新新索引进行重排,如果某个索引值当前不存在,就引入缺失值
>>>obj2
a    0.0
b    1.0
c    2.0
d    NaN
dtype: float64
>>>obj3 = Series(['blue','purple','yellow'],index=[0,2,4])
>>>obj3.reindex(range(6),method = 'ffill')   #对于时间序列这样的有序数据,重新索引时可能需要做一些插值处理。method选项即可达到此目的。
0      blue
1      blue
2    purple
3    purple
4    yellow
5    yellow
dtype: object
  • reindex的(插值)method选项
    ffill或pad #前向填充(或搬运)值
    bfill或backfill #后向填充(或搬运)值
>>>frame = DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'], columns = ['Oo','Tt','Cc'])
>>>frame

   Oo  Tt  Cc
a   0   1   2
c   3   4   5
d   6   7   8
>>>frame2 = frame.reindex(['a','b','c','d'])   #对于DataFrame,reindex可以修改(行)索引、列,或两个都修改。如果仅传入一个序列,则会重新索引行

    Oo   Tt   Cc
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关键字即可重新索引列
>>>states = ['Tt','Uu','Cc']
>>>frame.reindex(columns = states)

   Tt  Uu  Cc
a   1 NaN   2
c   4 NaN   5
d   7 NaN   8

#同时对行和列进行重新索引,而插值则只能按行应用(即轴0)
>>>frame.reindex(index=['a','b','c','d'],method='ffill',columns=states)

   Tt  Uu  Cc
a   1 NaN   2
b   1 NaN   2
c   4 NaN   5
d   7 NaN   8

#利用ix的标签索引功能,重新索引任务可以变得更简洁
>>>frame.ix[['a','b','c','d'],states]

    Tt  Uu   Cc
a  1.0 NaN  2.0
b  NaN NaN  NaN
c  4.0 NaN  5.0
d  7.0 NaN  8.0
  • reindex函数的参数
• index 用作索引的新序列。既可以是index序列,也可以是其他序列型的Python数据结构。index会被完全使用,就像没有任何复制一样 
method #插值(填充)方式 
fill_value #在重新索引的过程中,需要引入缺失值时使用的替代值 
limit #前向或后向填充时最大填充量 
level #在Multiindex的指定级别上匹配简单索引,否则选取其子集 
copy #默认为True,无论如何都复制;如果为False,则新旧相等就不复制

3.5 丢弃指定轴上的项

丢弃某条轴上的一个或多个项很简单,只要有一个索引数组或列表即可。由于需要执行一些数据整理和集合逻辑,所以drop方法返回的是一个在指定轴上删除了指定值的新对象

>>>obj = Series(np.arange(5),index = ['a','b','c','d','e'])
>>>obj

a    0
b    1
c    2
d    3
e    4
dtype: int32

>>>new_obj = obj.drop('c')

a    0
b    1
d    3
e    4
dtype: int32

3.6 索引、选取和过滤

>>>obj = Series(np.arange(5),index = ['a','b','c','d','e'])
>>>obj

a    0
b    1
c    2
d    3
e    4
dtype: int32

>>>obj['b]
1.0
>>>obj['a','b']
a  0
b  1
>>>obj[2:4]  #切片
c  2
d  3
>>>obj[obj<2]
a  0
b  1
>>>obj['b':'c']
b  1
c  2

>>>obj < 4  #布尔型索引

a     True
b     True
c     True
d     True
e    False
dtype: bool

#字段ix索引 >>>frame Oo Tt Cc a 0 1 2 c 3 4 5 d 6 7 8 >>>frame.ix[['a

','c '],['Cc ','Oo ']] Cc Oo a 2 0 c 5 3 >>>frame.ix[['a ','c '],[1,2]] Tt Cc a 1 2 c 4 5

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

3.7 算术运算和数据对齐

  • 对不同的索引的对象进行算术运算,在相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。
>>>s1 = Series(np.arange(4),index = ['a','c','d','e'])
>>>s2 = Series(np.arange(5),index = ['a','c','e','f','g'])

>>>s1
a    0
c    1
d    2
e    3
dtype: int32

>>>s2
a    0
c    1
e    2
f    3
g    4
dtype: int32

>>>s1 + s2   #自动的数据对齐操作在不重叠的索引处引入了NaN值
a    0.0
c    2.0
d    NaN
e    5.0
f    NaN
g    NaN
dtype: float64
  • fill_value #在对不同索引的对象进行算术运算时,数据操作不重叠处填充一个特殊值。
>>>s1.add(s2,fill_value=0)
a    0.0
c    2.0
d    2.0
e    5.0
f    3.0
g    4.0
dtype: float64

>>>s1.reindex(index = s2.index, fill_value = 0)  #在对Series和DataFrame重新索引时,也可以指定一个填充值

a    0
c    1
e    3
f    0
g    0
dtype: int32
  • 算术方法
• s1.add(s2) #用于加法的方法 
s1.sub(s2) #用于减法的方法 
s1.div(s2) #用于除法的方法 
s1.mul(s2) #用于乘法的方法

3.8 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]   #这就叫做广播(broadcasting)
array([[ 0.,  0.,  0.,  0.],
       [ 4.,  4.,  4.,  4.],
       [ 8.,  8.,  8.,  8.]])
#DataFrame和Series之间是算术运算将Series索引值默认匹配到DataFrame的列,然后沿着行一直向下广播
>>>frame = DataFrame(np.arange(12.).reshape((4,3)),columns = list('bde'), index = ['Uu','Oo','Tt','Or'])
>>>series = frame.ix[0]
>>>frame
     b     d     e
Uu  0.0   1.0   2.0
Oo  3.0   4.0   5.0
Tt  6.0   7.0   8.0
Or  9.0  10.0  11.0

>>>series
b    0.0
d    1.0
e    2.0
Name: Uu, dtype: float64

>>>frame - series  #如果索引找不到,则为NaN
      b    d    e
Uu  0.0  0.0  0.0
Oo  3.0  3.0  3.0
Tt  6.0  6.0  6.0
Or  9.0  9.0  9.0

#行在列上广播(即与每列做运算),则需用算术运算方法
>>>series2 = frame['d']
>>>series2
Uu    0.0
Oo    3.0
Tt    6.0
Or    9.0
Name: b, dtype: float64

>>>frame.sub(series2, axis=0)
      b    d    e
Uu  0.0  1.0  2.0
Oo  0.0  1.0  2.0
Tt  0.0  1.0  2.0
Or  0.0  1.0  2.0

3.9 函数应用和映射

  • NumPy的ufunc(元素级数组方法)也可用于操作pandas对象。
>>>frame = DataFrame(np.arange(12.).reshape((4,3)),columns = list('bde'), index = ['Uu','Oo','Tt','Or'])
>>>frame
     b     d     e
Uu  0.0   1.0   2.0
Oo  3.0   4.0   5.0
Tt  6.0   7.0   8.0
Or  9.0  10.0  11.0

>>>np.abs(frame) #求绝对值
      b     d     e
Uu  0.0   1.0   2.0
Oo  3.0   4.0   5.0
Tt  6.0   7.0   8.0
Or  9.0  10.0  11.0

>>>f = lambda x: x.max() - x.min()
>>>frame.appply(f)  #将函数应用到各列所形成的一维数组,apply方法实现
b    9.0
d    9.0
e    9.0
dtype: float64

>>>frame.apply(f,axis=1) #应用到行
Uu    2.0
Oo    2.0
Tt    2.0
Or    2.0
dtype: float64

3.10 排序和排名

  • obj.sort_index()方法将返回一个已排序的新对象。
>>>obj = Series(np.arange(5),index = ['e','c','a','d','b'])
>>>obj
e    0
c    1
a    2
d    3
b    4
dtype: int32

>>>obj2 = obj.sort_index()
>>>obj2
a    2
b    4
c    1
d    3
e    0
dtype: int32

>>>obj2.sort_index(ascending = False) #降序
e    0
d    3
c    1
b    4
a    2
dtype: int32

>>>obj2.order()  #按值排序。排序时,任何缺失值默认都会被会放到Series的末尾。
e    0
c    1
a    2
d    3
b    4
dtype: int32
  • 在DataFrame上,将一个或多个列的名字传递给by,即可对相应的列排序
>>>frame = DataFrame(np.arange(12.).reshape((4,3)),columns = list('bde'), index = ['Uu','Oo','Tt','Or'])
>>>frame
     b     d     e
Uu  0.0   1.0   2.0
Oo  3.0   4.0   5.0
Tt  6.0   7.0   8.0
Or  9.0  10.0  11.0

>>>frame.sort_index(by = 'b',ascending=False)  #按'b'列降序
      b     d     e
Or  9.0  10.0  11.0
Tt  6.0   7.0   8.0
Oo  3.0   4.0   5.0
Uu  0.0   1.0   2.0
  • 排名
    排名(ranking)跟排序关系密切,它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。它跟numpy.argsort产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。
>>>obj2 = Series([7,-5,7,4,2,0,4])
>>>obj2.rank()  #rank()是通过“为各组分配一个平均排名”的方式破坏平级关系的
0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64

>>>obj2.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
  • 排名时用于破坏平级关系的method选项
•  method = ‘average’ #默认:在相等分组中,为各个值分配平均排名 
 method = ‘min’ #使用整个分组的最小排名 
 method = ‘max’ #使用整个分组的最大排名 
 method = ‘first’ #按值在原始数据中的出现顺序分配排名

3.11 带有重复值的轴索引

  • 索引值对应多个值
>>>obj = Series(np.arange(5),index = ['a','a','b','b','c'])
a    0
a    1
b    2
b    3
c    4
dtype: int32

>>>obj.index.is_unique  #查询索引是否唯一
False

>>>obj['a']   #如果某个索引对应多个值,则返回一个Series,对应单个的,则返回一个标量值
a    0
a    1
>>>obj['c']
4
dtype: int32

#对DataFrame的行进行索引类似Series

3.12 汇总和计算描述统计

>>>frame = DataFrame([[1,np.nan],[3,-2],[np.nan,np.nan],[5,1]], index = ['a','b','c','d'], columns = ['one','two'])
>>>frame
   one  two
a  1.0  NaN
b  3.0 -2.0
c  NaN  NaN
d  5.0  1.0
>>>frame.sum()
one    9.0
two   -1.0
dtype: float64
>>>frame.mean(axis=1,skipna=False)   #axis=1是按列,skipna默认为True,排除缺失值。skipan=False表示不排除缺失值
a    NaN
b    0.5
c    NaN
d    3.0
dtype: float64
  • 约简方法的选项
    axis #默认=0按行,=1为按列
    skipna #排除缺失值,默认为True
    level #如果轴是层次化索引的(即multilindex),则根据level分组约简
>>>frame.idxmax()  #返回最大值的索引
one    d
two    d
dtype: object
  • 描述和汇总统计
• frame.count() #非NA值的数量 
frame.describe() #针对Series或各DataFrame列计算汇总统计 
frame.min()、frame.max() #计算最小值和最大值 
frame.argmin()、frame.argmax() #计算能够获取到最小值和最大值的索引位置(整数) 
frame.idxmin()、frame.idxmax() #计算最大值和最小值的索引值 
frame.quantile() #计算样本的分位数(0到1) 
frame.sum() #值的总和 
frame.mean() #值的平均数 
frame.median() #值的算术中位数(50%) 
frame.mad() #根据平均值计算平均绝对离差 
frame.var() #样本值的方差 
frame.std() #样本值的标准差 
frame.skew() #样本值的偏度(三阶矩) 
frame.kurt() #样本值的峰度(四阶矩) 
frame.cumsum() #样本值的累积和 
frame.cummin()、frame.cummax() #样本值的累积最大值和累积最小值 
frame.cumprod() #样本值的累积积 
frame.diff() #计算一阶差分(对时间序列很有用) 
frame.pct_change() #计算百分数变化

3.13 相关系数与协方差

frame.corr() #相关系数
frame.cov() #协方差矩阵

3.14 唯一值、值计数以及成员资格

>>>obj2 = Series(['c','a','d','a','a','b','b','c','c'])
>>>uni = obj2.unique()
>>>uni
array(['c', 'a', 'd', 'b'], dtype=object)

>>>obj2.value_counts()  #计算各个值出现的频率,默认降序排列
c    3
a    3
b    2
d    1
dtype: int64
  • 唯一值、值计数、成员资格方法
• obj2.isin() #计算一个表示“Series各值是否包含于传入的值序列中”的布尔型数组 
obj2.unique() #计算Series中的唯一值数组,按发现的书序返回 
obj2.value_counts() #返回一个Series,其索引为唯一值,其值为频率,按计数值降序排列

3.15 处理缺失数据

>>>obj2 = Series(['c','a','d','a','a','b','b','c','c'])
>>>obj2.isnull()
0    False
1    False
2    False
3    False
4    False
5    False
6    False
7    False
8    False
dtype: bool
  • NA处理方法
• obj2.dropna() #根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈值调节对缺失值的容忍度(默认丢弃任何含有缺失值的行) 
obj2.fillna() #用指定值或插值方法(如ffill或bfill)填充缺失数据 
obj2.isnull() #返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值NA,该对象的类型与源类型一样 
obj2.notnull() #isnull的否定式
  • 滤除缺失数据
>>>frame = DataFrame([[1,np.nan],[3,-2],[np.nan,np.nan],[5,1]], index = ['a','b','c','d'], columns = ['one','two'])
>>>frame
   one  two
a  1.0  NaN
b  3.0 -2.0
c  NaN  NaN
d  5.0  1.0
>>>frame2 = frame.dropna()  #默认丢弃全部缺失值的行
   one  two
b  3.0 -2.0
d  5.0  1.0

>>>frame3 = frame.dropna(how = 'all')   #丢弃全为NA的行,参数添加axis=1可按列丢弃
   one  two
a  1.0  NaN
b  3.0 -2.0
d  5.0  1.0
  • 填充缺失数据
>>>frame = DataFrame([[1,np.nan],[3,-2],[np.nan,np.nan],[5,1]], index = ['a','b','c','d'], columns = ['one','two'])
>>>frame
   one  two
a  1.0  NaN
b  3.0 -2.0
c  NaN  NaN
d  5.0  1.0
>>>frame.fillna(0)
   one  two
a  1.0  0.0
b  3.0 -2.0
c  0.0  0.0
d  5.0  1.0

参考文献《Python数据分析》