python之pandas用法详解

pandas是基于numpy构建的,使得数据分析工作变得更快更简单的高级数据结构和操作工具。

一、pandas数据结构

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

1.1 Series

Series是一种类似于一维数组的对象,它由一维数组(各种numpy数据类型)以及一组与之相关的数据标签(即索引)组成,仅由一组数据即可产生最简单的Series.

Series的字符串表现形式为:索引在左边,值在右边。如果没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的长度)的整数型索引。可以通过Series的values和index属性获取其数组表现形式和索引对象:

import numpy as np
import pandas as pd
from pandas import Series,DataFrame

#**********************************Series*************************************
obj=Series([2,4,7,8,9,3])
"""obj=
0    2
1    4
2    7
3    8
4    9
5    3
dtype: int64
"""
obj.values    #return:array([2, 4, 7, 8, 9, 3], dtype=int64)
obj.index     #return: RangeIndex(start=0, stop=6, step=1)
#创建对数据点进行标记的索引
obj2=Series([2,4,7,8,9,3],index=['a','b','c','d','e','f'])
"""obj2=
a    2
b    4
c    7
d    8
e    9
f    3
dtype: int64
"""
obj2.index   #return:Index(['a', 'b', 'c', 'd', 'e', 'f'], dtype='object')
#利用索引的方式选取Series的单个或一组值
obj2['c']   #return:7
obj2[['a','c','f']]
"""out:
a    2
c    7
f    3
dtype: int64
"""
#numpy数组运算(布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接
obj2[obj2>5]
obj2*2
np.exp(obj2)
"""
obj2[obj2>5]:      obj2*2:       np.exp(obj2):
c    7             a     4           a       7.389056
d    8             b     8           b      54.598150
e    9             c    14           c    1096.633158
dtype: int64       d    16           d    2980.957987
                   e    18           e    8103.083928
                   f     6           f      20.085537
                   dtype: int64      dtype: float64
"""
#可以将Series看成是一个有定长的有序字典,因为它是索引值到数据值的一个映射
#因此,一些字典函数也可以在这里使用:
'a' in obj2        #return:True
'h' in obj2        #return:False
2 in obj2.values   #return:True

#利用字典创建Series
dic={'l':1,'z':2,'h':3}
obj3=Series(dic)
"""obj3=
h    3
l    1
z    2
dtype: int64
"""
#若索引比字典的索引多,则与字典索引相匹配的则会被找到,并放置到相应的位置中
#而对应字找不到的索引,其结果则为NaN(即非数字,Not a Number,在pandas中,用于表示缺失或NA值)
ind=['l','z','h','a']
obj4=Series(dic,index=ind)
"""obj4=
l    1.0
z    2.0
h    3.0
a    NaN
dtype: float64
"""
#pandas中isnull和notnull函数用于检测缺失数据:
pd.isnull(obj4)    #等效于: obj4.isnull()
pd.notnull(obj4)
"""
pd.isnull(obj4):        pd.notnull(obj4)
l    False              l     True
z    False              z     True
h    False              h     True
a     True              a     False
dtype: bool             dtype: bool
"""
#算术运算中自动对齐不同索引的数据
obj3+obj4
"""out:
a    NaN
h    6.0
l    2.0
z    4.0
dtype: float64
"""
#Series对象本身及其索引都有一个name属性
obj4.name='myname'
obj4.index.name='letter'
"""obj4=
letter
l    1.0
z    2.0
h    3.0
a    NaN
Name: myname, dtype: float64
"""
#索引可以通过赋值的方式进行改变
obj4.index=['li','zi','hua','a']
"""obj4=
li     1.0
zi     2.0
hua    3.0
a      NaN
Name: myname, dtype: float64
"""

1.2 DataFrame

DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(公用同一个索引)。跟其他类似的数据结构相比,DataFrame中面向行和面向列的操作基本是平衡的。其实,DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或者别的一维数据结构)。

其中,可以输入给DataFrame构造器的数据类型及相关说明:

python之pandas用法详解_第1张图片

#*******************************DataFrame*************************************
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
#构建DataFrame
#最常用的一种是直接传入一个由等长列表或numpy数组组成的字典:
data={'names':['Bob','Jane','Jack','Ann'],
       'sex':['M','F','M','F'],
       'age':[21,30,26,28]}
frame=DataFrame(data)
"""没有指定索引,会自动加上索引,且全部列会被有序排列
frame=
   age names sex
0   21   Bob   M
1   30  Jane   F
2   26  Jack   M
3   28   Ann   F
"""
#若指定列序列,则会按照指定顺序排列
frame=DataFrame(data,columns=['names','sex','age'])
"""frame=
  names sex  age
0   Bob   M   21
1  Jane   F   30
2  Jack   M   26
3   Ann   F   28
"""
#若传入列在数据中找不到,会返回NA值
frame1=DataFrame(data,columns=['names','sex','age','id'],index=['a','b','c','d'])
"""frame1=
  names sex  age   id
a   Bob   M   21  NaN
b  Jane   F   30  NaN
c  Jack   M   26  NaN
d   Ann   F   28  NaN
"""
#通过类似字典标记或属性的方式,可以获取Series(列数据):
frame1['sex']
frame1.age
"""
frame1['sex']:                           frame1.age:
a    M                                    a      21
b    F                                    b      30
c    M                                    c      26
d    F                                    d      28
Name: sex, dtype: object                  Name: age, dtype: int64
"""
#行也可以通过位置或名称获取
#ix VS loc VS iloc
#loc——通过行标签索引行数据
frame1.loc('c')
#等效于
#iloc——通过行号获取行数据
frame1.iloc[2]
#ix--以上两种的混合,既可以用行号,也可以用行标签
frame1.ix[2]
frame1.ix['c']
"""result:
names    Jack
sex         M
age        26
id        NaN
Name: c, dtype: object
"""
#获取多行
#注意:使用行标签时,:两边是全包括,使用行号时是左闭右开
frame1.loc['b':'c']
frame1.iloc[2:4]
frame1.ix['b':'c']
frame1.ix[2:4]
"""result:
 names sex  age   id
c  Jack   M   26  NaN
d   Ann   F   28  NaN
"""
#利用ix、loc、iloc拓展获取列数据
#获取单列,如下所示,或将['sex']写成'sex',将不显示columns名
frame1.ix[:,['sex']]   #等效于frame1['sex']
frame1.loc[:,['sex']] 
frame1.ix[:,[1]] 
"""
frame1.ix[:,['sex']]:      VS       frame1.ix[:,'sex'] :
  sex
a   M                               a    M
b   F                               b    F
c   M                               c    M
d   F                               d    F
"""
#获取多列
frame1.ix[:,'sex':]
frame1.loc[:,'sex':]
frame1.iloc[:,1:4]
"""result:
  sex  age   id
a   M   21  NaN
b   F   30  NaN
c   M   26  NaN
d   F   28  NaN
"""
#给列赋值,赋值是列表或数组时,长度必须相匹配
frame1['id']=np.arange(4)    
"""frame1=
  names sex  age  id
a   Bob   M   21   0
b  Jane   F   30   1
c  Jack   M   26   2
d   Ann   F   28   3
"""
#若赋值的是一个Series,将精确匹配DataFrame的索引,空位将补上缺失值
frame1['id']=Series([11,12],index=['a','c'])
"""frame1=
  names sex  age    id
a   Bob   M   21  11.0
b  Jane   F   30   NaN
c  Jack   M   26  12.0
d   Ann   F   28   NaN
"""
#为不存在的列赋一个新列
frame1['Female']=frame1.sex=='F'
"""frame1=
  names sex  age    id  Female
a   Bob   M   21  11.0   False
b  Jane   F   30   NaN    True
c  Jack   M   26  12.0   False
d   Ann   F   28   NaN    True
"""
#删除列数据
del frame1['Female']
"""frame1=
  names sex  age    id
a   Bob   M   21  11.0
b  Jane   F   30   NaN
c  Jack   M   26  12.0
d   Ann   F   28   NaN
"""
#嵌套字典(字典的字典)作为参数,传入DataFrame
#外层字典的键作为列(columns),内层键作为行索引(index)
pop={'Nevada':{2001:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
frame2=DataFrame(pop)
"""frame2=
      Nevada  Ohio
2000     NaN   1.5
2001     2.4   1.7
2002     2.9   3.6
"""
#对结果进行转置
frame2.T
"""result:
        2000  2001  2002
Nevada   NaN   2.4   2.9
Ohio     1.5   1.7   3.6
"""
#显示指定索引
DataFrame(pop,index=[2001,2002,2003])
"""result:
      Nevada  Ohio
2001     2.4   1.7
2002     2.9   3.6
2003     NaN   NaN
"""
#跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据
frame2.values     #result:array([[ nan,  1.5],[ 2.4,  1.7],[ 2.9,  3.6]])

二、基本功能

2.1  重新索引-------reindex:创建一个适合新索引的新对象

reindex函数的参数:

python之pandas用法详解_第2张图片

Series中reindex方法:

#Series中的reindex方法
obj=Series([1.2,3.4,-7.8,5.6],index=['d','a','c','b'])
#rreindex会根据新索引重新排列,若索引值不存在,则引入缺省值
obj.reindex(['a','b','c','d','e'])
#还可设置缺省项的值
obj.reindex(['a','b','c','d','e'],fill_value=0)    #此时,上面结果中的NaN将变成0
"""
obj:            obj.reindex(['a','b','c','d','e']):
d    1.2             a    3.4
a    3.4             b    5.6
c   -7.8             c   -7.8
b    5.6             d    1.2
dtype: float64       e    NaN
                     dtype: float64
"""
#插值处理
#对于时间序列这样的有序序列,重新索引时需要做一些插值处理
obj1=Series(['yellow','pink','blue'],index=[0,2,4])
obj1.reindex(range(6),method='ffill')
"""obj1=
0    yellow
1    yellow
2      pink
3      pink
4      blue
5      blue
dtype: object
"""
python之pandas用法详解_第3张图片

DataFrame中reindex方法:

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

frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['US','UK','CN'])
"""frame=
   US  UK  CN
a   0   1   2
b   3   4   5
c   6   7   8
"""
frame1=frame.reindex(['a','b','c','e'])
#使用columns关键字即可重新索引列
states=['US','HK','CN']
frame.reindex(columns=states)
"""result:
   US  HK  CN
a   0 NaN   2
b   3 NaN   5
c   6 NaN   8
"""
#可以同时对行和列进行索引,但插值只能按照行(即轴0)应用
frame.reindex(index=['a','b','c','e'],method='ffill',columns=states)
"""
   US  HK  CN
a   0 NaN   2
b   3 NaN   5
c   6 NaN   8
e   6 NaN   8
"""
#利用ix索引功能,重新索引任务变得更加简洁
frame.ix[['a','b','c','e'],states]
"""
    US  HK   CN
a  0.0 NaN  2.0
b  3.0 NaN  5.0
c  6.0 NaN  8.0
e  NaN NaN  NaN
"""

2.2 丢弃指定轴上的项------drop方法

由于需要执行一些数据整理和集合逻辑,所以drop方法返回的是一个在指定轴上删除了指定值的新对象。

#对于Series对象
obj=Series([1.2,3.4,-7.8,5.6],index=['d','a','c','b'])
obj.drop('c')               #返回的是新对象,obj没变
obj.drop(['a','d'])
"""
obj:            obj.drop('c'):               obj.drop(['a','d']):
d    1.2             d    1.2                      c   -7.8
a    3.4             a    3.4                      b    5.6
c   -7.8             b    5.6                      dtype: float64
b    5.6             dtype: float64
dtype: float64                        
"""
#对于DataFrame,可以删除任意轴上的索引值:
frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['US','UK','CN'])
frame.drop('a')   #默认axis=0
frame.drop(['US','UK'],axis=1)
"""
frame:              frame.drop('a'):        frame.drop(['US','UK'],axis=1):
   US  UK  CN          US  UK  CN                CN
a   0   1   2       b   3   4   5            a    2
b   3   4   5       c   6   7   8            b    5
c   6   7   8                                c    8
"""

2.3 算术运算和数据对齐

pandas最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是索引对的并集。

#对于Series对象
s1=Series([1.2,3.4,-7.8,5.6],index=['d','a','c','b'])
s2=Series([1.1,2.2,3.3,4.4.,5.5,6.6],index=['a','b','c','d','e','f'])
s1+s2     #在不重叠的地方引入了NA值,且缺失值会在算术运算过程中传播
"""result:
a    4.5
b    7.8
c   -4.5
d    5.6
e    NaN
f    NaN
dtype: float64
"""

对于DataFrame对象,对齐操作会发生在列和行上,具体过程和Series一样。

2.4 DataFrame和Series之间的运算

跟Numpy数组一样,DataFrame和Series之间的算术运算也是有明确规定的,和不同形状的数组之间的运算类似,也具有广播效应。

默认情况下,DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行已知向下传播(行传播):

frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['US','UK','CN'])
s=frame.ix['a']
frame-s
"""
frame:                 s:                     frame-s:
   US  UK  CN         US  0                      US  UK  CN
a   0   1   2         UK  1                   a   0   0   0
b   3   4   5         CN  2                   b   3   3   3
c   6   7   8                                 c   6   6   6
"""

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

frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['US','UK','CN'])
s1=frame['CN']
frame.sub(s1,axis=0)  #axis=0不能少,否则运算时,默认沿着行向下传播
"""
frame:                 s1:                     frame.sub(s1,axis=0)
   US  UK  CN            CN                      US  UK  CN
a   0   1   2         a   2                   a  -2  -1   0
b   3   4   5         b   5                   b  -2  -1   0
c   6   7   8         c   8                   c  -2  -1   0
"""
frame-s1   #或frame.sub(s1)
"""result:
   CN  UK  US   a   b   c
a NaN NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN NaN
"""

算术方法:

python之pandas用法详解_第4张图片

2.5 函数应用和映射

numpy中ufuncs(元素级数组方法)也可以用于pandas对象,例:

np.exp(frame)
"""
           US           UK           CN
a    1.000000     2.718282     7.389056
b   20.085537    54.598150   148.413159
c  403.428793  1096.633158  2980.957987
"""

另一个常见的操作是,将函数应用到由各列或行所形成的一维数组上,DataFrame的apply方法即可实现该功能:

f=lambda x:x.max()-x.min()
frame.apply(f)           #函数应用到每列所形成一维数组
frame.apply(f,axis=1)    #函数应用到每行所形成一维数组
"""
frame:              
   US  UK  CN        frame.apply(f):         frame.apply(f,axis=1)
a   0   1   2        US    6                       a    2
b   3   4   5        UK    6                       b    2
c   6   7   8        CN    6                       c    2
"""

2.6 排序和排名

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

2.6.1 排序

#排序
obj=Series([1.2,3.4,-7.8,5.6],index=['d','a','c','b'])
#索引排序
obj.sort_index()
#值排序
obj.sort_values()
"""
obj:             obj.sort_index():          obj.sort_values():
d    1.2             a    3.4                   c   -7.8
a    3.4             b    5.6                   d    1.2
c   -7.8             c   -7.8                   a    3.4
b    5.6             d    1.2                   b    5.6
"""
frame=DataFrame(np.arange(9).reshape((3,3)),index=['a','b','c'],columns=['US','UK','CN'])
#索引排序,分轴0和轴1,若需要按照哪行排序,可利用by='',锁定某行
frame.sort_index(axis=1)
#值排序
#axis=0代表对列操作,by='CN'代表对name为'CN'的列处理,ascending默认为True,代表升序排
frame.sort_values(by='CN',axis=0,ascending=False)
"""
frame:              frame.sort_index(axis=1):   frame.sort_values(by='CN',axis=0,ascending=False):
   US  UK  CN          CN  UK  US                        US  UK  CN
a   0   1   2       a   2   1   0                     c   6   7   8
b   3   4   5       b   5   4   3                     b   3   4   5
c   6   7   8       c   8   7   6                     a   0   1   2   
"""
#在排序中,默认缺失值都会被放到最后
obj1=Series([4,np.nan,7,np.nan,-3,5])
"""result:
4   -3.0
0    4.0
5    5.0
2    7.0
1    NaN
3    NaN
dtype: float64
"""

2.6.2 排名

排名(ranking)跟排序关系密切,且它会增设一个排名值(从1开始,一直到数组中有效数据的数量)。它跟numpy.argsort产生的间接排序索引差不多,只不过它可以根据某种规则破坏平级关系。默认情况下,rank是通过”为各组分配一个平均排名“的方式破坏平级关系的。

rank()函数中,用于破坏平级关系的method选项:

python之pandas用法详解_第5张图片

#排名:
obj=Series([7,-5,7,4,2,0,4])
obj.rank()
obj.rank(method='first')
"""
obj:           obj.rank():            obj.rank(method='first'):
0    7          0    6.5                  0    6.0
1   -5          1    1.0                  1    1.0
2    7          2    6.5                  2    7.0
3    4          3    4.5                  3    4.0
4    2          4    3.0                  4    3.0
5    0          5    2.0                  5    2.0
6    4          6    4.5                  6    5.0
"""
frame=DataFrame({'b':[3,2,4,1],'a':[7,5,2,9],'c':[3,9,6,2]})
frame.rank(axis=1)
"""
frame:                  frame.rank(axis=1):
   a  b  c                      a    b    c
0  7  3  3                 0  3.0  1.5  1.5
1  5  2  9                 1  2.0  1.0  3.0
2  2  4  6                 2  1.0  2.0  3.0
3  9  1  2                 3  3.0  1.0  2.0
"""

三、汇总和计算描述统计

pandas对象拥有一组常用的数学和统计方法。它们大部分都属于简约和汇总统计,用于从Series中提取单个值(如sum或mean)或从DataFrame的行或列中提取一个Series。更对应的numpy数组方法,它们都是基于没有缺失数据的假设而构建的。

3.1与描述统计相关的函数:

python之pandas用法详解_第6张图片

python之pandas用法详解_第7张图片

3.2 函数中常见的选项:

python之pandas用法详解_第8张图片

3.3部分代码示例:

#汇总和统计
df=DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],columns=['one','two'])
#计算每列的和,默认排除NaN
df.sum()
#计算每行的和,默认排除NaN
df.sum(axis=1)
#计算每行的和,设置skipna=False,NaN参与计算,结果仍为NaN
df.sum(axis=1,skipna=False)
"""
df:                    df.sum():       df.sum(axis=1):     df.sum(axis=1,skipna=False):
    one  two         one    9.25         0    1.40               0     NaN
0  1.40  NaN         two   -5.80         1    2.60               1    2.60
1  7.10 -4.5                             2    0.00               2     NaN
2   NaN  NaN                             3   -0.55               3   -0.55
3  0.75 -1.3
"""
obj=Series(['a','b','a','d']*4)
obj.describe()
"""
count     16
unique     3
top        a
freq       8
dtype: object
"""

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

常见方法:(对于Series对象

python之pandas用法详解_第9张图片

相关代码:

obj=Series(['a','d','a','b']*4)
unique=obj.unique()    #结果未排序 return:array(['a', 'd', 'b'], dtype=object)
obj.value_counts()     #结果按值频率降序排序
#等效于   pd.value_counts(obj,sort=True)
"""result:
a    8
d    4
b    4
dtype: int64
"""  
obj1=Series(['a','b','c','d'])
#判断矢量化集合的成员资格
obj1.isin(['b','d'])
"""
0    False
1     True
2    False
3     True
dtype: bool
"""
对于DataFrame对象,可以使用apply函数和以上函数联合使用。
frame=DataFrame({'b':[3,2,4,1],'a':[3,5,2,1],'c':[3,3,2,2]})
#fillna(0)将nan值的位置上填补0
frame.apply(pd.value_counts).fillna(0)
"""
     a    b    c
1  1.0  1.0  0.0
2  1.0  1.0  2.0
3  1.0  1.0  2.0
4  0.0  1.0  0.0
5  1.0  0.0  0.0
"""

四、处理缺失数据

缺失数据是大部分数据分析应用中都很常见。pandas的设计目标之一就是让缺失数据的处理任务尽量轻松。pandas使用浮点值(NaN)表示浮点和非浮点数据中的缺失数据。它只是一个便于被检测出来的标记而已。python中的内置none也会被当做NA处理。

NA的处理方法:

python之pandas用法详解_第10张图片


你可能感兴趣的:(数据分析工具)