Python数据分析笔记----第五章pandas入门

1.pandas数据结构介绍

1.1 Series

Series是一种一维的数据型对象,它包含一个值序列(与Numpy中的类型相似),并且包含数据的标签,称为索引(index

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

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

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

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

pd.Series(序列)可以生成一个Series的对象,序列是有序的数据结构,集合不行,但是字典可以,列表,元组等都行

Series的属性

  • index

  • values

  • name

  • index.name

    In [32]: obj.name = 'zhangfan'
    
    In [33]: obj.index.name = 'zf'
    
    In [34]: obj
    Out[34]:
    zf
    a    1
    b    2
    c    3
    Name: zhangfan, dtype: int64
    

Series与Numpy数组几乎相同,唯一不同点是,Series既可以像Numpy数组一样,通过整数来索引值,也可以通过Series自定义的其他索引来索引值

  • 可以对Series使用Numpy函数或Numpy风格的操作

    In [17]: obj
    Out[17]:
    a    1
    b    2
    c    3
    dtype: int64
    
    In [18]: obj[obj>1]#bool数组
    Out[18]:
    b    2
    c    3
    dtype: int64
        
    In [19]: np.exp(obj)#通用函数
    Out[19]:
    a     2.718282
    b     7.389056
    c    20.085537
    dtype: float64
    
    In [20]: obj + obj#类似numpy数组中的逐元素操作
    Out[20]:
    a    2
    b    4
    c    6
    dtype: int64
    
    In [21]: obj[0]#通过整数索引来索引值
    Out[21]: 1
    
  • 当pd.Series(字典,index)传入的是一个字典的时候,index参数表示的是,选择那些键所对应的键值对构成Series,不存在的键的值对应NaN

    In [27]: pd.Series(dict(zip([1,2,3],list('abc'))),index=[3,2,1])
    Out[27]:
    3    c
    2    b
    1    a
    dtype: object
    
  • pd.isnull(Series)或者Series.isnull()可以用来判断Series中的值是否是NaN

    pd.notnull(Series)或者Series.notnull()是上面的对立操作

  • 自动对齐

    当把两个Series相加的时候,两个Series会自动对齐index,将index相同的值相加在一起

1.2 DataFrame

简介:DataFrame表示的是矩阵的数据表,包含以排序的列集合,每一列可以是不同的值类型。DataFrame中既有行索引也有列索引,它可以被视作一个共享相同索引的Series的字典

1.2.1 属性:
  • index
  • columns
  • index.name
  • columns.name
  • values
  • dtypes
In [60]: df1
Out[60]:
zf        a  b  c
zhangfan
0         1  4  7
1         2  5  8
2         3  6  9

In [61]: df1.index
Out[61]: RangeIndex(start=0, stop=3, step=1, name='zhangfan')

In [62]: df1.columns
Out[62]: Index(['a', 'b', 'c'], dtype='object', name='zf')

In [63]: df1.index.name
Out[63]: 'zhangfan'

In [64]: df1.columns.name
Out[64]: 'zf'

In [82]: df1.values
Out[82]:
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]], dtype=int64)

In [85]: df1.dtypes
Out[85]:
zf
a    int64
b    int64
c    int64
dtype: object
1.2.2 生成DataFrame
  • 包含等长度列表或Numpy数组的字典来形成DataFrame

    In [35]: data = {'a':[1,2,3],'b':[4,5,6],'c':[7,8,9]}
    
    In [36]: df1 = pd.DataFrame(data)
    
    In [37]: df1
    Out[37]:
       a  b  c
    0  1  4  7
    1  2  5  8
    2  3  6  9
    
    • 因为传入的是一个字典,因此可以通过columns属性来改变列的顺序或选择出现的列

      In [39]: df2 = pd.DataFrame(data,columns=['b','c','e'])
      
      In [40]: df2
      Out[40]:
         b  c    e
      0  4  7  NaN
      1  5  8  NaN
      2  6  9  NaN
      
    • df.head(nums)

      df.head()表示选择df的前几行,nums参数表示前几行,如果不给nums参数,则默认表示前五行

      In [41]: df1.head(2)
      Out[41]:
         a  b  c
      0  1  4  7
      1  2  5  8
      
    • DataFrame中的一列,可以按字典型标记或属性那样检索为Series

      DataFrame中选取的列是数据的视图,而不是拷贝,因此对选取的列进行修改会映射到原DataFrame

      In [47]: df1
      Out[47]:
         a  b  c
      0  1  4  7
      1  2  5  8
      2  3  6  9
      
      In [48]: df1['a']#字符串列名需要加引号
      Out[48]:
      0    1
      1    2
      2    3
      Name: a, dtype: int64
      
      In [49]: df1.a#字符串列名不需要加引号
      Out[49]:
      0    1
      1    2
      2    3
      Name: a, dtype: int64
      
    • DataFrame中的一行,可以通过df.loc[行名]来索引

    • 增加一列和删除一列

      In [65]: df1['d'] = np.arange(3)
      
      In [66]: df1
      Out[66]:
      zf        a  b  c  d
      zhangfan
      0         1  4  7  0
      1         2  5  8  1
      2         3  6  9  2
      
      In [67]: del df1['d']
      
      In [68]: df1
      Out[68]:
      zf        a  b  c
      zhangfan
      0         1  4  7
      1         2  5  8
      2         3  6  9
      
      
    • 增加一行和删除一行

      In [68]: df1
      Out[68]:
      zf        a  b  c
      zhangfan
      0         1  4  7
      1         2  5  8
      2         3  6  9
      
      In [112]: df1.drop(2)
      Out[112]:
      zf        a  b  c
      zhangfan
      0         1  4  7
      1         2  5  8
      
  • 包含字典的嵌套字典

    In [69]: pop = {'a':{'m':1,'n':2,'o':3},'b':{'m':4,'n':5,'o':6},'c':{'m':7,'n':8,'o':9}}
    
    In [70]: df3 = pd.DataFrame(pop)
    
    In [71]: df3
    Out[71]:
       a  b  c
    m  1  4  7
    n  2  5  8
    o  3  6  9
    
    • DataFrame可以像Numpy中的数组一样转置

      In [71]: df3
      Out[71]:
         a  b  c
      m  1  4  7
      n  2  5  8
      o  3  6  9
      
      In [72]: df3.T
      Out[72]:
         m  n  o
      a  1  2  3
      b  4  5  6
      c  7  8  9
      
    • 可以显示的给定index参数,让DataFrame按照给定的index序列排列

      In [73]: pop
      Out[73]:
      {'a': {'m': 1, 'n': 2, 'o': 3},
       'b': {'m': 4, 'n': 5, 'o': 6},
       'c': {'m': 7, 'n': 8, 'o': 9}}
      
      In [74]: df3 =  pd.DataFrame(pop,index=['o','n','m'
          ...: ])
      
      In [75]: df3
      Out[75]:
         a  b  c
      o  3  6  9
      n  2  5  8
      m  1  4  7
      
  • 包含Series的字典也可以用于构造DataFrame

    In [75]: df3
    Out[75]:
       a  b  c
    o  3  6  9
    n  2  5  8
    m  1  4  7
    
    In [77]: pd.DataFrame({'e':df3.a,'f':df3.c})
    Out[77]:
       e  f
    o  3  9
    n  2  8
    m  1  7
    
1.3 索引对象(pd.Index())

索引对象是不可变对象,索引对象的这个特点使得在多种数据结构中分享索引对象更为安全

In [86]: index = pd.Index([1,2,3])

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

In [88]: index[0] = 0
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-88-1441e135a2b4> in <module>()
----> 1 index[0] = 0

~\AppData\Roaming\Python\Python37\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
   4079
   4080     def __setitem__(self, key, value):
-> 4081         raise TypeError("Index does not support mutable operations")
   4082
   4083     def __getitem__(self, key):

TypeError: Index does not support mutable operations(翻译:索引不支持可变操作)

与Python集合不同:pandas索引对象可以包含重复的标签

In [91]: dup_labels = pd.Index(['a','a','b','b'])

In [92]: dup_labels
Out[92]: Index(['a', 'a', 'b', 'b'], dtype='object')

根据重复标签进行筛选,会选取所有重复标签对应的数据

1.3.1 索引对象常用方法
  • index1.append(index2) 将索引对象index2添加到index1后面,产生一个新的索引
  • index.unique() 计算索引的唯一值序列
  • 索引对象常用方法
1.4 重建索引

重建索引,不会改变索引,只会重新排列索引,

  • series.reindex() , 会将数据按照新的索引进行排列

    series.reindex()有个参数method,可以传入‘ffill’表示前向填充,'bfill’表示后向填充

  • 在DataFrame中,reindex可以改变行索引和列索引,也可以同时改变二者。当仅传入一个序列时,结果中的行会重建索引

    In [108]: df3
    Out[108]:
       a  b  c
    o  3  6  9
    n  2  5  8
    m  1  4  7
    
    In [106]: df3.reindex(columns=['a','x'])
    Out[106]:
       a   x
    o  3 NaN
    n  2 NaN
    m  1 NaN
    
    In [109]: df3.reindex(columns=['a','x'],method='ffill')#对于不存在的columns,ffill会填充最后一列
    Out[109]:
       a  x
    o  3  9
    n  2  8
    m  1  7
    
    In [110]: df3.reindex(['o','x'],method='bfill')#对于不存在的行,bfill会填充第一行
    Out[110]:
       a  b  c
    o  3  6  9
    x  3  6  9
    
1.5 删除df的行列

df.drop(行名或列名,axis=0)

行名或列名可以是一个列表

In [115]: df1
Out[115]:
zf        a  b  c
zhangfan
0         1  4  7
1         2  5  8
2         3  6  9

In [116]: df1.drop(2)
Out[116]:
zf        a  b  c
zhangfan
0         1  4  7
1         2  5  8

In [117]: df1.drop(['b','c'],axis=1)#axis = 1可以用axis='columns'来代替
Out[117]:
zf        a
zhangfan
0         1
1         2
2         3
1.6索引、选择与过滤

Series的索引支持nupy中的索引方式,另外Series还有独有的索引方式

In [126]: obj
Out[126]:
zf
a    1
b    2
c    3
Name: zhangfan, dtype: int64

In [127]: obj['a':'c']#与普通的切片不同的是,Series的切片会包含尾部的
Out[127]:
zf
a    1
b    2
c    3
Name: zhangfan, dtype: int64
1.6.1 DataFrame的索引
  • 行索引

    In [130]: df3
    Out[130]:
       a  b  c
    o  3  6  9
    n  2  5  8
    m  1  4  7
    
    In [131]: df3['a']
    Out[131]:
    o    3
    n    2
    m    1
    Name: a, dtype: int64
    
    In [132]: df3[['a','c']]#列名必须用中括号括起来
    Out[132]:
       a  c
    o  3  9
    n  2  8
    m  1  7
    
    In [133]: df3.a
    Out[133]:
    o    3
    n    2
    m    1
    Name: a, dtype: int64
    
  • 列索引

    In [137]: df3
    Out[137]:
       a  b  c
    o  3  6  9
    n  2  5  8
    m  1  4  7
    
    In [138]: df3[df3['a']>1]#bool索引
    Out[138]:
       a  b  c
    o  3  6  9
    n  2  5  8
    
    In [139]: df3[:2]#整数行索引必须这样,不能通过单个整数直接索引
    Out[139]:
       a  b  c
    o  3  6  9
    n  2  5  8
    
    In [140]: df3[0]   ######行索引不能这样索引,这样会报错
    
  • 省去麻烦,直接使用loc和iloc选择器,也支持Series

1.7 算术和数据对齐

将两个DataFrame相加时,pandas会自动将两者按照index和columns全相同的元素相加,不相同的则只保留行和列的索引,值为NaN

In [140]: df5 = pd.DataFrame(np.arange(9).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])

In [141]: df6 = pd.DataFrame(np.arange(12).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])

In [142]: df5
Out[142]:
          b  c  d
Ohio      0  1  2
Texas     3  4  5
Colorado  6  7  8

In [143]: df6
Out[143]:
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

In [144]: df5 + df6
Out[144]:
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN
1.7.1 使用填充值的算术方法
  • add, radd +
  • sub, rsub -
  • div, rdiv /
  • floordiv, rfloordiv //
  • mul, rmul *
  • pow, rpow **
In [142]: df5
Out[142]:
          b  c  d
Ohio      0  1  2
Texas     3  4  5
Colorado  6  7  8

In [143]: df6
Out[143]:
        b   d   e
Utah    0   1   2
Ohio    3   4   5
Texas   6   7   8
Oregon  9  10  11

In [144]: df5 + df6
Out[144]:
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN

In [145]: 3//2
Out[145]: 1

In [146]: df5.add(df6,fill_value=0)
Out[146]:
            b    c     d     e
Colorado  6.0  7.0   8.0   NaN
Ohio      3.0  1.0   6.0   5.0
Oregon    9.0  NaN  10.0  11.0
Texas     9.0  4.0  12.0   8.0
Utah      0.0  NaN   1.0   2.0
1.8 函数应用和映射

Numpy中的通用函数(逐元素数组方法)对DataFrame对象也有效

In [151]: df4 = pd.DataFrame(np.random.randn(4,3))

In [152]: df4
Out[152]:
          0         1         2
0 -1.971583  1.182724 -1.030719
1 -0.450175  0.656434 -0.594173
2 -0.310988  0.398418 -0.659847
3 -0.054048  0.114076 -1.713716

In [153]: np.abs(df4)
Out[153]:
          0         1         2
0  1.971583  1.182724  1.030719
1  0.450175  0.656434  0.594173
2  0.310988  0.398418  0.659847
3  0.054048  0.114076  1.713716
1.8.1 apply函数

df.apply(函数名,axis)可以将“函数”应用到df的每一个axis上面

In [154]: df4
Out[154]:
          0         1         2
0 -1.971583  1.182724 -1.030719
1 -0.450175  0.656434 -0.594173
2 -0.310988  0.398418 -0.659847
3 -0.054048  0.114076 -1.713716

In [155]: df4.apply(lambda x:x.max()-x.min(),axis='columns')
Out[155]:
0    3.154307
1    1.250607
2    1.058265
3    1.827792
dtype: float64

大部分常用的数组统计(比如sum和mean)都是DataFrame的方法,因此计算统计值时使用apply并不是必需的

传递给apply的函数并不是一定要返回一个标量值,也可以返回带有多个值的Series:

In [157]: def f(x):
     ...:     return pd.Series([x.max(),x.min()],index=['max','min'])
     ...:
     ...:

In [158]: df4.apply(f)
Out[158]:
            0         1         2
max -0.054048  1.182724 -0.594173
min -1.971583  0.114076 -1.713716

1.8.2 applymap函数

df.applymap(函数名)可以将函数应用到df中的每一个元素

In [159]: df4.applymap(lambda x:'%.2f' % x)
Out[159]:
       0     1      2
0  -1.97  1.18  -1.03
1  -0.45  0.66  -0.59
2  -0.31  0.40  -0.66
3  -0.05  0.11  -1.71

回顾:map(函数名,序列)的作用是对序列中的每一个元素调用指定函数

applymap函数存在是因为Series有map方法

In [165]: df4[1]
Out[165]:
0    1.182724
1    0.656434
2    0.398418
3    0.114076
Name: 1, dtype: float64

In [166]: df4[1].map(lambda x:'%.2f' % x)
Out[166]:
0    1.18
1    0.66
2    0.40
3    0.11
Name: 1, dtype: object

Series的map函数还可以传入一个字典,表示将Series中的每个元素当做字典的键,在字典中查询相应的值

In [50]: data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
    ...:                               'Pastrami', 'corned beef', 'Bacon',
    ...:                               'pastrami', 'honey ham', 'nova lox'],
    ...:                      'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
    ...:

In [51]: data
Out[51]:
          food  ounces
0        bacon     4.0
1  pulled pork     3.0
2        bacon    12.0
3     Pastrami     6.0
4  corned beef     7.5
5        Bacon     8.0
6     pastrami     3.0
7    honey ham     5.0
8     nova lox     6.0

In [52]: meat_to_animal = {
    ...:   'bacon': 'pig',
    ...:   'pulled pork': 'pig',
    ...:   'pastrami': 'cow',
    ...:   'corned beef': 'cow',
    ...:   'honey ham': 'pig',
    ...:   'nova lox': 'salmon'
    ...: }

In [53]:

In [53]: lowercased = data['food'].str.lower()
    ...: 
    ...: lowercased
    ...: data['animal'] = lowercased.map(meat_to_animal)#此处map函数传入的是一个字典
    ...: data
    ...:
    ...:
Out[53]:
          food  ounces  animal
0        bacon     4.0     pig
1  pulled pork     3.0     pig
2        bacon    12.0     pig
3     Pastrami     6.0     cow
4  corned beef     7.5     cow
5        Bacon     8.0     pig
6     pastrami     3.0     cow
7    honey ham     5.0     pig
8     nova lox     6.0  salmon
1.9 排序和排名
1.9.1 排序
  • df.sort_index(axis, ascending)

    • axis:在哪个周上面排序
    • ascending:是否是升序
    In [167]: frame = pd.DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
    
    In [168]: frame.sort_index()
    Out[168]:
           d  a  b  c
    one    4  5  6  7
    three  0  1  2  3
    
    In [169]: frame.sort_index(axis='columns')#axis='columns'等价于axis=1
    Out[169]:
           a  b  c  d
    three  1  2  3  0
    one    5  6  7  4
    
    In [170]: frame.sort_index(axis='columns',ascending=False)
    Out[170]:
           d  c  b  a
    three  0  3  2  1
    one    4  7  6  5
    
  • df.sort_values(by)

    默认是升序,在升序情况下,缺失值会被排到Series尾部

    对于Series来说不需要by参数,但对于DataFrame来说,by参数必不可少

    In [171]: frame
    Out[171]:
           d  a  b  c
    three  0  1  2  3
    one    4  5  6  7
    
    In [172]: frame.sort_values(axis=1,ascending=False)
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-172-eaa4efc29b60> in <module>()
    ----> 1 frame.sort_values(axis=1,ascending=False)
    
    TypeError: sort_values() missing 1 required positional argument: 'by'
    
    In [173]: frame.sort_values(axis=1,ascending=False,by='three')
    Out[173]:
           c  b  a  d
    three  3  2  1  0
    one    7  6  5  4
    

    还可以给by参数传递一个列表

1.9.2 排名

rank(axis,ascending,method)

  • axis:在那个轴上面排名
  • ascending:是否是升序
  • method:如何分配平级关系
    • ‘average’:默认的,使用每个组中分配平均排名
    • ‘min’:对整个组使用最小排名
    • ‘max’:对整个组使用最大排名
    • ‘first’:按照值在数据中出现的次序分配排名
    • ‘dense’:类似于method=‘first’,但组间排名总是增加1,而不是一个组中相等的元素数量

rank用法

1.10 描述性统计的概述与计算

与Numpy中的统计方法类似,但是不同的是,pandas中内建了处理缺失值的功能

除非整行或整列都是NA,否则NA值是被自动排除的,可以通过skipna(bool)参数来实现不排除NA值

In [179]: df
Out[179]:
    one  two
a  1.40  NaN
b  7.10 -4.5
c   NaN  NaN
d  0.75 -1.3

In [180]: df.sum(axis='columns')
Out[180]:
a    1.40
b    2.60
c    0.00
d   -0.55
dtype: float64

In [181]: df.sum(axis='columns',skipna=False)
Out[181]:
a     NaN
b    2.60
c     NaN
d   -0.55
dtype: float64
    

其他常用统计方法

  • idxmin()和idxmax()返回的是最小值和最大值的索引值
  • cumsum()累计求和
  • describe()产生多个汇总统计,对于非数值型数据,describe()方法产生另一种汇总统计
  • count()非NA值的个数
  • argmin(),argmax()最小值和最大值的索引值的位置(整数)
  • quantile()计算样本的从0到1间的分位数
  • median()中位数
  • prod()所有值的积
  • var()
  • std()
  • 其他

相关性和协方差

  • corr()相关系数
  • cov()协方差
In [182]: df4
Out[182]:
          0         1         2
0 -1.971583  1.182724 -1.030719
1 -0.450175  0.656434 -0.594173
2 -0.310988  0.398418 -0.659847
3 -0.054048  0.114076 -1.713716

In [183]: df4.corr()
Out[183]:
          0         1         2
0  1.000000 -0.948712 -0.141207
1 -0.948712  1.000000  0.404908
2 -0.141207  0.404908  1.000000

In [184]: df4.cov()
Out[184]:
          0         1         2
0  0.749292 -0.373008 -0.062753
1 -0.373008  0.206308  0.094421
2 -0.062753  0.094421  0.263578

In [185]: df4[0].corr(df4[1])
Out[185]: -0.9487122337221459

In [186]: df4[0].cov(df4[1])
Out[186]: -0.37300831221892944

In [187]: df4.corrwith(df4[0])
Out[187]:
0    1.000000
1   -0.948712
2   -0.141207
dtype: float64

1.11 唯一值、计数和成员属性
  • series.unique()

    In [188]: obj = pd.Series(['c','a','d','a','a','b','b','c','c'])
    
    In [189]: obj.unique()
    Out[189]: array(['c', 'a', 'd', 'b'], dtype=object)
    
  • series.values_count()计数

    In [190]: obj.value_counts()#会自动将结果降序排列
    Out[190]:
    a    3
    c    3
    b    2
    d    1
    dtype: int64
    
  • pd.values_count(series,sort:bool)

    In [192]: pd.value_counts(obj,sort=False)
    Out[192]:
    b    2
    c    3
    a    3
    d    1
    dtype: int64
    
  • isin()执行向量化成员属性检查

    In [194]: obj.isin(['b','c'])
    Out[194]:
    0     True
    1    False
    2    False
    3    False
    4    False
    5     True
    6     True
    7     True
    8     True
    dtype: bool
    

    举例:

    In [8]: data = pd.DataFrame({'Qu1':[1,3,4,3,4],'Qu2':[2,3,1,2,3],'Qu3':[1,5,2,4,4]})
    
    In [9]: data
    Out[9]:
       Qu1  Qu2  Qu3
    0    1    2    1
    1    3    3    5
    2    4    1    2
    3    3    2    4
    4    4    3    4
    
    In [10]: data.apply(pd.value_counts).fillna(0)
    Out[10]:
       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
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值