Jupyter notebook 阅读效果更佳
函数应用和映射
numpy 的ufunc(元素级数组方法)也可用于pandas对象
import pandas as pd
import numpy as np
frame = pd. DataFrame( np. random. randn( 4 , 3 ) , columns= list ( 'bde' ) ,
index= [ 'Utah' , 'Ohio' , 'Texas' , 'Oregon' ] )
frame
b d e Utah 0.003772 1.021304 0.287353 Ohio -0.512751 0.738990 -0.721568 Texas -1.074487 -0.973134 2.026376 Oregon 1.616839 -2.127216 0.698915
np. abs ( frame)
b d e Utah 0.003772 1.021304 0.287353 Ohio 0.512751 0.738990 0.721568 Texas 1.074487 0.973134 2.026376 Oregon 1.616839 2.127216 0.698915
另一种常见的操作是将函数应用到各列或者行所形成的一维数组上。DataFrame的apply方法可以实现
f = lambda x: x. max ( ) - x. min ( )
frame. apply ( f)
b 2.691326
d 3.148520
e 2.747944
dtype: float64
上述代码在列上执行,返回最大值和最小值的差,也是一个Series。 如果传入一个参数,则可以在行上执行
frame. apply ( f, axis= 'columns' )
Utah 1.017532
Ohio 1.460558
Texas 3.100863
Oregon 3.744055
dtype: float64
许多常见的方法都被实现为DataFrame的方法,而不必使用apply()方法 传递到apply的函数不是必须返回一个标量,可以返回有多个值组成的Series
def f ( x) :
return pd. Series( [ x. min ( ) , x. max ( ) ] , index = [ 'min' , 'max' ] )
frame. apply ( f)
b d e min -1.074487 -2.127216 -0.721568 max 1.616839 1.021304 2.026376
元素级的python函数也是可以用的,可以使用applymap()
format = lambda x: '%.2f' % x
frame. applymap( format )
b d e Utah 0.00 1.02 0.29 Ohio -0.51 0.74 -0.72 Texas -1.07 -0.97 2.03 Oregon 1.62 -2.13 0.70
frame[ 'e' ] . map ( format )
Utah 0.29
Ohio -0.72
Texas 2.03
Oregon 0.70
Name: e, dtype: object
排序和排名
要对行或者列索引进行排序,可以使用sort_index()方法,它返回一个排好序的新的对象
obj = pd. Series( range ( 4 ) , index= [ 'd' , 'a' , 'b' , 'c' ] )
obj
d 0
a 1
b 2
c 3
dtype: int64
obj. sort_index( )
a 1
b 2
c 3
d 0
dtype: int64
frame = pd. DataFrame( np. arange( 8 ) . reshape( 2 , 4 ) , index= [ 'three' , 'one' ] , columns= [ 'd' , 'a' , 'b' , 'c' ] )
frame
frame. sort_index( axis= 1 )
frame. sort_index( axis= 0 )
frame. sort_index( axis= 1 , ascending= False )
obj. sort_values( ascending= False )
c 3
b 2
a 1
d 0
dtype: int64
对DataFrame按值排序(默认的是 升序,按列)
frame. sort_values( axis= 1 , by= 'one' )
frame. sort_values( by= 'b' )
obj = pd. Series( [ np. nan, 4 , 7 , - 3 , 2 , np. nan] )
obj. sort_values( )
3 -3.0
4 2.0
1 4.0
2 7.0
0 NaN
5 NaN
dtype: float64
frame. sort_values( by= [ 'b' , 'a' ] )
排名会从1开始一直到数组中有效数据的数量。默认情况下,rank是通过“为各组分配一个平均排名”的方式破坏平级关系的
obj = pd. Series( [ 7 , - 5 , 7 , 4 , 2 , 0 , 4 ] )
obj
0 7
1 -5
2 7
3 4
4 2
5 0
6 4
dtype: int64
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. 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
frame = pd. DataFrame( { 'b' : [ 4.3 , 7 , - 3 , 2 ] , 'a' : [ 0 , 1 , 0 , 1 ] , 'c' : [ - 2 , 5 , 8 , - 2.5 ] } )
frame
b a c 0 4.3 0 -2.0 1 7.0 1 5.0 2 -3.0 0 8.0 3 2.0 1 -2.5
frame. rank( axis= 0 )
b a c 0 3.0 1.5 2.0 1 4.0 3.5 3.0 2 1.0 1.5 4.0 3 2.0 3.5 1.0
下表列出了所有用于破坏平衡等级关系的method
带有重复标签的额轴索引
之前所有范例都有着唯一的轴标签(索引值)。虽然许多pandas函数(如reindex)都要求标签唯一,但这并不是强制性的。
obj = pd. 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
对于带有重复值的索引,数据选取的行为将会有些不同。如果某个索引对应多个值,则返回一个Series;而对应单个值的,则返回一个标量值:
obj[ 'a' ]
a 0
a 1
dtype: int64
obj[ 'c' ]
4
df = pd. DataFrame( np. random. randn( 4 , 3 ) , index= [ 'a' , 'a' , 'b' , 'b' ] )
df
0 1 2 a 0.486488 -0.691133 -0.297861 a -0.176100 1.307201 -1.073343 b 1.149503 0.224737 2.220832 b 0.988378 -1.293291 -0.645180
df. loc[ 'b' ]
0 1 2 b 1.149503 0.224737 2.220832 b 0.988378 -1.293291 -0.645180
汇总和计算描述统计
pandas对象拥有一组常用的数学和统计方法,它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取一个Series。跟对应的NumPy数组方法相比,它们都是基于没有缺失数据的假设而构建的。
df = pd. DataFrame( [ [ 1.4 , np. nan] , [ 7.1 , - 4.5 ] , [ np. nan, np. nan] , [ 0.75 , - 1.3 ] ] ,
index= [ 'a' , 'b' , 'c' , 'd' ] ,
columns= [ 'one' , 'two' ] )
df
one two a 1.40 NaN b 7.10 -4.5 c NaN NaN d 0.75 -1.3
df. sum ( )
one 9.25
two -5.80
dtype: float64
'''传入axis='columns'或axis=1将会按行进行求和运算:'''
df. sum ( axis= 1 )
a 1.40
b 2.60
c 0.00
d -0.55
dtype: float64
'''NA值会自动被排除,除非整个切片(这里指的是行或列)都是NA。通过skipna选项可以禁用该功能:'''
df. mean( axis= 1 , skipna= False )
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
下表列出了约简方法的常用选项
'''有些方法如idxmax和idxmin 返回的是间接统计(如达到最大值或者最小值的索引)'''
df. idxmin( )
one d
two b
dtype: object
'''有些方法是累计型的'''
df. cumsum( )
one two a 1.40 NaN b 8.50 -4.5 c NaN NaN d 9.25 -5.8
'''还有的既不是累加型的也不是简约型的,如describe,用于一次性产生多个汇总统计'''
df. describe( )
one two count 3.000000 2.000000 mean 3.083333 -2.900000 std 3.493685 2.262742 min 0.750000 -4.500000 25% 1.075000 -3.700000 50% 1.400000 -2.900000 75% 4.250000 -2.100000 max 7.100000 -1.300000
'''对于非数值型数据,describe会产生另一种汇总统计'''
obj = pd. Series( [ 'a' , 'a' , 'b' , 'c' ] * 4 )
obj
0 a
1 a
2 b
3 c
4 a
5 a
6 b
7 c
8 a
9 a
10 b
11 c
12 a
13 a
14 b
15 c
dtype: object
obj. describe( )
count 16
unique 3
top a
freq 8
dtype: object
下表列出了所有的于描述统计相关的方法
相关系数和协方差
import pandas as pd
import numpy as py
import pandas_datareader. data as web
'''使用pandas-dadtareader下载数据:股票信息'''
all_data = { ticker: web. get_data_yahoo( ticker)
for ticker in [ 'AAPL' , 'IBM' , 'MSFT' , 'GOOG' ] }
price = pd. DataFrame( { ticker: data[ 'Adj Close' ] for ticker, data in all_data. items( ) } )
volime = pd. DataFrame( { ticker: data[ 'Volume' ] for ticker, data in all_data. items( ) } )
returns = price. pct_change( )
returns. tail( )
AAPL IBM MSFT GOOG Date 2018-10-24 -0.034302 -0.030486 -0.053469 -0.048003 2018-10-25 0.021898 -0.005974 0.058444 0.042695 2018-10-26 -0.015924 -0.013128 -0.012373 -0.021998 2018-10-29 -0.018770 -0.041269 -0.029076 -0.047962 2018-10-30 0.004994 -0.035440 -0.001155 0.015812
'''Series的corr方法用于计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov用于计算协方差:'''
returns[ 'MSFT' ] . corr( returns[ 'IBM' ] )
0.4729644703546016
returns[ 'MSFT' ] . cov( returns[ 'IBM' ] )
8.186106814767513e-05
'''因为MSFT是一个合理的python属性,还可以使用更加简洁的方式选择列'''
returns. MSFT. corr( returns. IBM)
0.4729644703546016
'''DataFrame的corr和cov方法将以DataFrame的形式分别返回完整的相关系数或协方差矩阵:'''
returns. corr( )
AAPL IBM MSFT GOOG AAPL 1.000000 0.359901 0.423805 0.436335 IBM 0.359901 1.000000 0.472964 0.398317 MSFT 0.423805 0.472964 1.000000 0.519982 GOOG 0.436335 0.398317 0.519982 1.000000
'''利用DataFrame的corrwith方法,你可以计算其列或行跟另一个Series或DataFrame之间的相关系数。
传入一个Series将会返回一个相关系数值Series(针对各列进行计算)'''
returns. corrwith( returns. IBM)
AAPL 0.359901
IBM 1.000000
MSFT 0.472964
GOOG 0.398317
dtype: float64
唯一值、值计数、成员资格
obj = pd. Series( [ 'c' , 'a' , 'd' , 'a' , 'a' , 'b' , 'b' , 'c' , 'c' ] )
'''函数unique,可以得到Series中的唯一值数组'''
obj. unique( )
array(['c', 'a', 'd', 'b'], dtype=object)
'''value_counts用于计算一个Series中各值出现的频率'''
obj. value_counts( )
a 3
c 3
b 2
d 1
dtype: int64
'''value_counts还有一个方法可以用于任何数组或者序列'''
pd. value_counts( obj. values, sort= False )
c 3
a 3
d 1
b 2
dtype: int64
'''isin用于判断矢量化结合的成员资格,可以用于过滤列中的子集'''
mask = obj. isin( [ 'b' , 'c' ] )
mask
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool
obj[ mask]
0 c
5 b
6 b
7 c
8 c
dtype: object
'''于isin类似的是Index.get_indexer方法,它可以给你一个索引数组,从可能包含重复值的数组到另一个不同的数组'''
to_match = pd. Series( [ 'c' , 'a' , 'b' , 'b' , 'c' , 'a' ] )
unique_vals = pd. Series( [ 'c' , 'b' , 'a' ] )
pd. Index( unique_vals) . get_indexer( to_match)
array([0, 2, 1, 1, 0, 2], dtype=int32)
下表给出了几个方法
'''有时可能希望得到DataFrame中多个相关列的一张柱状图'''
data = pd. DataFrame( { 'Qu1' : [ 1 , 3 , 4 , 3 , 4 ] , 'Qu2' : [ 2 , 3 , 1 , 2 , 3 ] , 'Qu3' : [ 1 , 5 , 2 , 4 , 4 ] } )
data
Qu1 Qu2 Qu3 0 1 2 1 1 3 3 5 2 4 1 2 3 3 2 4 4 4 3 4
result = data. apply ( pd. value_counts) . fillna( 0 )
result
Qu1 Qu2 Qu3 1 1.0 1.0 1.0 2 0.0 2.0 1.0 3 2.0 2.0 0.0 4 2.0 0.0 2.0 5 0.0 0.0 1.0