Python3 pandas入门

pandas的数据结构介绍

pandas有两个主要数据结构:Series和DataFrame。

Series

Series是一种类似一维数组的对象,由一组数据和与之相关的索引组成。

创建Series

第一种方式,直接传入一个列表或元组等序列数据,如果没有指定索引,会自动创建一个从0到N-1 的整数型索引。

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

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

In [5]: s2=pd.Series(np.arange(4),index=['a','b','c','d'])                                         

In [6]: s2                                                                                         
Out[6]: 
a    0
b    1
c    2
d    3
dtype: int64

第二种方式,传入一个字典,字典的键会变成Series的索引,字典的值变成Series的值。但是Series的索引和字典的键不同的是,Series的索引之间可以重复。以字典为参数创建Series对象时,可以传入索引序列,指定索引顺序。如果传入的索引在字典里找不到对应的值,Series会自动补充缺失值(NaN)。

In [14]: s_dic={"k1":"v1","k2":"v2","k3":"v3"}                                                     

In [15]: s3=pd.Series(s_dic,index=["k3","k2","k1"])                                                

In [16]: s3                                                                                        
Out[16]: 
k3    v3
k2    v2
k1    v1
dtype: object


In [22]: s4=pd.Series(s_dic,index=["k3","k2","k4"])                                                

In [23]: s4                                                                                        
Out[23]: 
k3     v3
k2     v2
k4    NaN
dtype: object

Series操作

通过values和index属性获取数组和索引对象。 

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

In [7]: s1.values                                                                                  
Out[7]: array([1, 2, 3])

可以使用索引的方式选取Series中的单个或一组值。

In [11]: s2                                                                                        
Out[11]: 
a    0
b    1
c    2
d    3
dtype: int64

In [12]: s2['a']                                                                                   
Out[12]: 0

In [13]: s2[['c','d']]                                                                             
Out[13]: 
c    2
d    3
dtype: int64

使用NumPy的函数或者类似NumPy运算会保留索引和值的链接。可以把Series对象看作是有序字典。

使用Series的isnull和notnull检测缺失数据。

In [24]: s4.isnull()                                                                               
Out[24]: 
k3    False
k2    False
k4     True
dtype: bool


In [25]: s4.notnull()                                                                              
Out[25]: 
k3     True
k2     True
k4    False
dtype: bool

 Series对象之间的运算会自动将索引对齐,对于不同时存在与两个Series对象的索引会取并集。

In [26]: s3+s4                                                                                     
Out[26]: 
k1     NaN
k2    v2v2
k3    v3v3
k4     NaN
dtype: object

DataFrame

DataFrame(简记为DF)是一个表格型的数据,既有行索引又有列索引,也可以看作由Series组成的字典。

创建DF数组

  1. 传入一个由等长的列表或NumPy数组组成的字典。DF会自动加上索引,如果传入列索引,DF会根据传入的索引序列将列排列。
  2. 传入一个嵌套字典,这个字典会被DF解释为:外层的键作为列名,内层的键会被合并作为索引,对于内层键对不上的值会补上缺失值(NaN)。
  3. 传入由Series组成的字典,和上面的方式类似,Series的索引会被DF合并,无法合并的值会被补上缺失值(NaN)。
In [27]: p1=pd.DataFrame({"A":[0,1,2],"B":[3,4,5],"C":[6,7,8]})                                    

In [28]: p1                                                                                        
Out[28]: 
   A  B  C
0  0  3  6
1  1  4  7
2  2  5  8

In [29]: p2=pd.DataFrame({"A1":{"a1":1,"a2":2,"a3":3},"B1":{"a1":4,"a2":5,"a3":6},"C1":{"a1":7,"a2"
    ...: :8,"a3":9}})                                                                              

In [30]: p2                                                                                        
Out[30]: 
    A1  B1  C1
a1   1   4   7
a2   2   5   8
a3   3   6   9

In [31]: p3=pd.DataFrame({"s3":s3,"s4":s4})                                                        

In [32]: p3                                                                                        
Out[32]: 
     s3   s4
k1   v1  NaN
k2   v2   v2
k3   v3   v3
k4  NaN  NaN

列索引

通过类似字典的形式或属性可以获取一个DF的一个列(Series类型)。

In [33]: p1['A']                                                                                   
Out[33]: 
0    0
1    1
2    2
Name: A, dtype: int64

In [34]: p1.A                                                                                      
Out[34]: 
0    0
1    1
2    2
Name: A, dtype: int64

以索引的方式获取多个列。

In [38]: p1[['C','B']]                                                                             
Out[38]: 
   C  B
0  6  3
1  7  4
2  8  5

行索引

使用loc方法以字典的方式获取单行。

In [52]: p3.loc['k1']                                                                              
Out[52]: 
s3     v1
s4    NaN
Name: k1, dtype: object

使用切片的方式获取多行。

In [56]: p3[:1]                                                                                    
Out[56]: 
    s3   s4
k1  v1  NaN

In [57]: p3['k1':]                                                                                 
Out[57]: 
     s3   s4
k1   v1  NaN
k2   v2   v2
k3   v3   v3
k4  NaN  NaN

DF操作

del可以删除DF的列,只能删除单列。

In [61]: del p1['A']                                                                               

In [62]: p1                                                                                        
Out[62]: 
   B  C
0  3  6
1  4  7
2  5  8

 通过索引返回的数据是DF的视图,对视图的任何修改都会反映到原数据。

In [64]: p1[['B','C']]=1                                                                           

In [65]: p1                                                                                        
Out[65]: 
   B  C
0  1  1
1  1  1
2  1  1

使用DF的index属性可以得到DF的行索引对象, columns属性可以得到DF的列索引对象,values属性得到一个像ndarray的数组对象。

In [66]: p1.index 
Out[66]: RangeIndex(start=0, stop=3, step=1)

In [67]: p1.columns                                                                                
Out[67]: Index(['B', 'C'], dtype='object')

In [68]: p1.values                                                                                 
Out[68]: 
array([[1, 1],
       [1, 1],
       [1, 1]])

索引对象

Series和DF的Index对象是不可变的。

In [72]: p1.index[0]=1                                                                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-72-1a8caf92d83a> in <module>
----> 1 p1.index[0]=1

~/anaconda3/lib/python3.7/site-packages/pandas/core/indexes/base.py in __setitem__(self, key, value)
   3936 
   3937     def __setitem__(self, key, value):
-> 3938         raise TypeError("Index does not support mutable operations")
   3939 
   3940     def __getitem__(self, key):

TypeError: Index does not support mutable operations

 Index对象可以包含重复的标签

In [74]: p1.index=[1,1,1]                                                                          

In [75]: p1                                                                                        
Out[75]: 
   B  C
1  1  1
1  1  1
1  1  1

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_monotonic 当个元素均大于等于前一个元素时,返回True
is_unique 当Index没有重复值时,返回True
unique 计算Index中唯一值的数组

基本功能

重新索引

DF和Series对象的index方法可以为数据重新创建索引,索引值不存在会引入缺失值(NaN)。reindex并不会原地修改原对象的索引,而是返回一个新的对象。

In [102]: s5=pd.Series(data=['v1','v2','v3','v4'],index=list("abcd"))                              

In [103]: s5.reindex(index=list("abce"))                                                           
Out[103]: 
a     v1
b     v2
c     v3
e    NaN
dtype: object

 对于一些有序数据,重新索引可能需要做一些向前或向后插值处理,reindex的method参数即可达到这个目的。

reindex的method选项

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

DF传入关键字参数axis="columns"修改列索引。

In [106]: p4                                                                                       
Out[106]: 
   A  B   C   D
a  0  1   2   3
b  4  5   6   7
c  8  9  10  11

In [107]: p4.reindex(['A','B','C','E'],axis="columns")                                             
Out[107]: 
   A  B   C   E
a  0  1   2 NaN
b  4  5   6 NaN
c  8  9  10 NaN

 reindex函数的参数

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

丢弃指定轴上的项

使用Series、DF的drop方法可以删除任意轴上的索引值。通过关键字参数axis指定轴,不传axis默认为0轴,axis=1或axis=“columns”指定列。

In [111]: s1                                                                                       
Out[111]: 
0    0
1    1
2    2
3    3
dtype: int64

In [113]: s1.drop(1)                                                                               
Out[113]: 
0    0
2    2
3    3
dtype: int64

In [114]: p1                                                                                       
Out[114]: 
   B  C
a  1  1
b  1  1
c  1  1

In [115]: p1.drop(['C'],axis="columns")                                                            
Out[115]: 
   B
a  1
b  1
c  1

drop方法不会在原数组上修改, 会返回一个修改以后的数组。如果现在原数组上修改,需要传入关键字参数inplace=True,传入inplace=True后不会有返回值。

索引、选取和过滤

Series的索引方式和NumPy数组类似,Series还支持非整数索引,并且Series用切片选取时,其末端是包含的。

In [118]: s2                                                                                       
Out[118]: 
a    0
b    1
c    2
d    3
dtype: int64

In [119]: s2['b':'d']                                                                              
Out[119]: 
b    1
c    2
d    3
dtype: int64

 用一个值或序列对DF进行索引会得到一个或多个列。使用切片的方式选取行。

In [121]: p4                                                                                       
Out[121]: 
   A  B   C   D
a  0  1   2   3
b  4  5   6   7
c  8  9  10  11

In [122]: p4['C']                                                                                  
Out[122]: 
a     2
b     6
c    10
Name: C, dtype: int64

In [123]: p4[['C','D']]                                                                            
Out[123]: 
    C   D
a   2   3
b   6   7
c  10  11

In [124]: p4[:2]                                                                                   
Out[124]: 
   A  B  C  D
a  0  1  2  3
b  4  5  6  7

还可以使用布尔型数组对DF索引。

In [126]: p4[p4>=6]                                                                                
Out[126]: 
     A    B     C     D
a  NaN  NaN   NaN   NaN
b  NaN  NaN   6.0   7.0
c  8.0  9.0  10.0  11.0

 还可以用loc和iloc(整数索引)行索引选取。

In [127]: p4.loc[['a','b']]                                                                        
Out[127]: 
   A  B  C  D
a  0  1  2  3
b  4  5  6  7

In [133]: p4.iloc[[0,1]]                                                                           
Out[133]: 
   A  B  C  D
a  0  1  2  3
b  4  5  6  7

DF的索引选项

类型 说明
df[val] 从DF选取单列或一组列;在特殊情况下比较便利:布尔型数组(过滤行)、切片(行切片)、或布尔型DF
df.loc[val] 通过标签,选取DF的单个行或一组行
df.loc[:,val] 通过标签选取单列或一组列
df.loc[val1,val2] 通过标签,同时选取行和列
df.iloc[where] 通过整数位置,从DF选取单个行或一组行
df.iloc[:,where] 通过整数位置,从DF选取单个列或一组列
df.iloc[where_i,where_j] 通过整数行和列,同时选取行和列
df.at[label_i,label_j] 通过行和列标签,选取单一的变量
df.iat[i,j] 通过行和列的位置(整数),选取单一的标量
reindex 通过标签选取行或列
get_value,set_value 通过行和列标签选取单一值

算术运算和数据对齐

DF对象间进行算术运算时,会将数据先根据索引对齐后再运算。如果存在不同的索引,结果将是两个DF索引的并集。

In [138]: p2                                                                                       
Out[138]: 
    A1  B1  C1
a1   1   4   7
a2   2   5   8
a3   3   6   9

In [139]: p4                                                                                       
Out[139]: 
   A  B   C   D
a  0  1   2   3
b  4  5   6   7
c  8  9  10  11

In [140]: p2.add(p4,fill_value=0)                                                                  
Out[140]: 
      A   A1    B   B1     C   C1     D
a   0.0  NaN  1.0  NaN   2.0  NaN   3.0
a1  NaN  1.0  NaN  4.0   NaN  7.0   NaN
a2  NaN  2.0  NaN  5.0   NaN  8.0   NaN
a3  NaN  3.0  NaN  6.0   NaN  9.0   NaN
b   4.0  NaN  5.0  NaN   6.0  NaN   7.0
c   8.0  NaN  9.0  NaN  10.0  NaN  11.0

自动对齐索引的操作会在索引不重叠的地方补入NaN值,缺失值会在算术运算过程中广播。有时候运算过程中有NaN值无法计算,这时候需要对NaN值去一个可以计算的值替代NaN,就可以使用关键字参数fill_value把NaN值替换成替代值。

用于Series和DF的算术方法 

方法 说明
add,radd 用于加法(+)的方法
sub,rsub 用于减法(-)的方法
div,rdiv 用于除法(/)的方法
floordiv,rfloordiv 用于整除(//)的方法
mul,rmul 用于乘法(*)的方法
pow,rpow 用于指数(**)的方法

DF和Series之间的运算

一般情况下DF的列名回合Series的索引对齐后,在行上进行广播。如果某个索引只存在DF中或Series中找不到,则结果索引会变成DF和Series索引的并集。

In [163]: s2                                                                                       
Out[163]: 
a    0
b    1
c    2
d    3
dtype: int64

In [164]: p5                                                                                       
Out[164]: 
   a  b   c   d
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11

In [165]: p5+s2                                                                                    
Out[165]: 
   a   b   c   d
0  0   2   4   6
1  4   6   8  10
2  8  10  12  14

 如果希望DF和Series的运算在列上,需要传入关键字参数axis=1或axis="columns"。

In [172]: s0=p5.loc[0]                                                                             

In [173]: p5.sub(s0,axis=1)                                                                        
Out[173]: 
   a  b  c  d
0  0  0  0  0
1  4  4  4  4
2  8  8  8  8

函数应用的和映射

NumPy的元素级方法也可用于操作pandas对象。

In [11]: p1=pd.DataFrame(np.arange(24).reshape(4,6),index=list('abcd'),columns=list('qwerty'))     

In [12]: np.sqrt(p1)                                                                               
Out[12]: 
          q         w         e         r         t         y
a  0.000000  1.000000  1.414214  1.732051  2.000000  2.236068
b  2.449490  2.645751  2.828427  3.000000  3.162278  3.316625
c  3.464102  3.605551  3.741657  3.872983  4.000000  4.123106
d  4.242641  4.358899  4.472136  4.582576  4.690416  4.795832

对于需要将操作作用到DF的行或列上的情况 ,可以使用apply函数。apply默认对DF的列操作。

In [13]: def f(series): 
    ...:     return max(series) 
    ...:                                                                                           

In [14]: p1.apply(f)                                                                               
Out[14]: 
q    18
w    19
e    20
r    21
t    22
y    23
dtype: int64

 如果传递axis=1或axis='columns'参数到apply函数里,这个函数将在每行执行。

In [16]: p1.apply(f,axis=1)                                                                        
Out[16]: 
a     5
b    11
c    17
d    23
dtype: int64

 apply不但可以返回一个标量,还可以返回一个Series。

In [17]: def f1(series): 
    ...:     return series[::-1] 
    ...:                                                                                           

In [18]: p1.apply(f1)                                                                              
Out[18]: 
    q   w   e   r   t   y
d  18  19  20  21  22  23
c  12  13  14  15  16  17
b   6   7   8   9  10  11
a   0   1   2   3   4   5

元素级的python函数也可以被使用到DF对象中,需要使用applymap函数。

In [20]: def f3(x): 
    ...:     return x%2 
    ...:                                                                                           

In [21]: p1.applymap(f3)                                                                           
Out[21]: 
   q  w  e  r  t  y
a  0  1  0  1  0  1
b  0  1  0  1  0  1
c  0  1  0  1  0  1
d  0  1  0  1  0  1

如果需要用元素级的python函数对Series操作,可以Series的map函数和apply函数。

In [34]: s1                                                                                        
Out[34]: 
a    5
b    6
c    7
d    8
e    9
dtype: int64

In [35]: def f4(x): 
    ...:     return x+5 
    ...:                                                                                           

In [36]: s1.map(f4)                                                                                
Out[36]: 
a    10
b    11
c    12
d    13
e    14
dtype: int64

In [37]: s1.apply(f4)                                                                              
Out[37]: 
a    10
b    11
c    12
d    13
e    14
dtype: int64

排序和排名

sort_index可以对索引排序,默认按照升序排列索引。

In [8]: p1                                                                                         
Out[8]: 
    Q   W   E   R   T
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

In [9]: p1.sort_index(axis=1)                                                                     
Out[9]: 
    E   Q   R   T   W
a   2   0   3   4   1
b   7   5   8   9   6
c  12  10  13  14  11
d  17  15  18  19  16
e  22  20  23  24  21

 传入axis=1或axis="columns"在列上排序,传入ascending=False按照索引降序排列。

In [12]: p1.sort_index(axis=1,ascending=False)                                                     
Out[12]: 
    W   T   R   Q   E
a   1   4   3   0   2
b   6   9   8   5   7
c  11  14  13  10  12
d  16  19  18  15  17
e  21  24  23  20  22

若要按值对Series排序,可以使用sort_values方法。传入ascending=False倒序排列。

Out[13]: 
a    0
b    1
c    2
d    3
e    4
dtype: int64

In [16]: s1.sort_values(ascending=False)                                                           
Out[16]: 
e    4
d    3
c    2
b    1
a    0
dtype: int64

按值给DF排序,使用sort_values方法,与Series不同的是DF必须传列名或列名的序列给关键字参数by。传入ascending=False倒序排列。

In [21]: p1                                                                                        
Out[21]: 
    Q   W   E   R   T
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

In [22]: p1.sort_values(by=['Q','E'],ascending=False)                                              
Out[22]: 
    Q   W   E   R   T
e  20  21  22  23  24
d  15  16  17  18  19
c  10  11  12  13  14
b   5   6   7   8   9
a   0   1   2   3   4

In [23]: p1.sort_values(by='Q')                                                                    
Out[23]: 
    Q   W   E   R   T
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

排名会从1开始一直到数组中有效数据的数量。Series和DF的rank方法会给每组数据分配一个平均排名的方式来破坏平级关系。倒序排名需要传入关键字参数ascending=False。

In [28]: s2                                                                                        
Out[28]: 
a    1
b    1
c    2
d    2
e    3
f    4
g    5
dtype: int64

In [29]: s2.rank()                                                                                 
Out[29]: 
a    1.5
b    1.5
c    3.5
d    3.5
e    5.0
f    6.0
g    7.0
dtype: float64

 排名时用于破坏平级关系的方法

方法 说明
'average' 默认:在相等分组中,为各个值分配平均排名

'min'

使用整个分组的最小排名
'max' 使用整个分组最大的排名

'first' 

按值在原始数据中的出现顺序分配排名

'dense'

类似于'min'方法,但是排名总是在组间增加1,而不是组中相同的元素数

汇总和计算描述统计

DF的各方法传入axis参数会axis的轴运算。在一些运算中NA值会自动被过滤掉,除非整个行或列都是NaN,通过skipna选项可以禁用这个功能。

In [33]: p1                                                                                        
Out[33]: 
    Q   W   E   R   T
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

In [34]: p1.sum(axis=1)                                                                            
Out[34]: 
a     10
b     35
c     60
d     85
e    110
dtype: int64

约简方法的选项

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

描述和汇总统计

方法 说明
count 非NA的数量
describe 针对Series和DF各列的计算汇总统计
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 计算百分数变化

相关系数与协方差

Series的corr用来计算两个Series中重叠的、非NA的、按索引对齐的相关系数,cov计算两个Series的协方差。

In [59]: s1                                                                                        
Out[59]: 
a    0
b    1
c    2
d    3
e    4
dtype: int64

In [60]: s2                                                                                        
Out[60]: 
a    1
b    1
c    2
d    2
e    3
f    4
g    5
dtype: int64

In [61]: s1.cov(s2)                                                                                
Out[61]: 1.25

In [62]: s1.corr(s2)                                                                               
Out[62]: 0.9449111825230679

DF的corr和cov方法将以DF的形式分别返回完整的相关系数或协方差矩阵。

In [66]: p1                                                                                        
Out[66]: 
    Q   W   E   R   T
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

In [67]: p1.cov()                                                                                  
Out[67]: 
      Q     W     E     R     T
Q  62.5  62.5  62.5  62.5  62.5
W  62.5  62.5  62.5  62.5  62.5
E  62.5  62.5  62.5  62.5  62.5
R  62.5  62.5  62.5  62.5  62.5
T  62.5  62.5  62.5  62.5  62.5

In [68]: p1.corr()                                                                                 
Out[68]: 
     Q    W    E    R    T
Q  1.0  1.0  1.0  1.0  1.0
W  1.0  1.0  1.0  1.0  1.0
E  1.0  1.0  1.0  1.0  1.0
R  1.0  1.0  1.0  1.0  1.0
T  1.0  1.0  1.0  1.0  1.0

DF的corrwith方法可以计算DF的行和列与另一个Series或DF之间的相关系数。传入一个Series会返回一个相关系数值Series(针对各列进行计算)。传入一个DF将会计算按列名配对的相关系数。传入axis='columns'即可按行计算。无论如何,在计算相关系数之前,所有的数据项都会按标签对齐。

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

唯一值、值计数、成员资格方法

方法 说明
isin 计算一个表示“Series各值是否包含于传入的值序列中”的布尔型数组
match 计算一个数组中的各值到另一个不同数值的正树索引;对于数据对其和连接类型的操作十分有用
unique 计算Series中的唯一值数组,按发现的顺序返回
value_counts 返回一个Series,其索引为唯一值,其值为频率,按计数值降序排列
posted @ 2019-09-20 15:36  Wuliwawa  阅读(311)  评论(0编辑  收藏  举报