【读书笔记】《利用Python进行数据分析》第2版_第五章 Pandas入门

  • pandas经常是和其他数值计算工具,比如NumPy和SciPy,以及数据可视化工具比如matplotlib一起使用。
  • pandas支持大部分NumPy的数组计算,尤其是数组函数以及没有for循环的各种数据处理。
  • pandas处理表格型或异质型数据,NumPy处理同质型的数值类数组数据
  • 常用的类:Series和DataFrame

5.1 pandas数据结构介绍

Series

  • Series是一种一维的数组型对象,它包含了一个值序列,并且包含了数据标签,称为索引(index)。

  • 默认生成索引从0到N-1(N是数据的长度),通过values属性和index属性分别获得Series对象的值和索引。

  • 通常会创建一个索引序列,用标签标识每个数据点

    import pandas as pd
    obj2 = pd.Series([4,7,-5,3],index=['d','b','a','c'])
    obj2
    """
    d    4
    b    7
    a   -5
    c    3
    dtype: int64
    """
    obj2.index # Index(['d', 'b', 'a', 'c'], dtype='object')
    # 使用标签进行索引
    obj2['a'] # -5
    obj2[['c','a','d']] # 包含的不是数字而是字符串,作为索引列表
    """
    c    3
    a   -5
    d    4
    dtype: int64
    """
    
  • 可以使用类似NumPy的风格操作:比如使用布尔值数组进行过滤,与标量相乘,或是应用数学函数,这些操作将保存索引值连接。

  • Series是一个长度固定且有序的字典,在你可能会使用字典的上下文中,也可以使用Series。

  • 使用字典可以生成Series:pd.Series(字典对象)

    • 可以将字典排序后生成Series

      sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah':5000}
      states = ['California','Ohio','Oregon','Texas']
      obj4= pd.Series(sdata,index=states)
      obj4
      """
      California        NaN  # not a number pandas标记缺失值
      Ohio          35000.0
      Oregon        16000.0
      Texas         71000.0
      dtype: float64
      """
      
  • pandas中使用isnull和notnull函数来检查缺失数据,“缺失”或“NA”表示缺失数据

    • pd.isnull(obj4)
    • pd.notnull(obj4)
    • isnull和notnull也是Series的实例方法:obj4.isnull()
  • Series可用来在数学操作中自动对齐

  • Series对象自身和其索引都有name属性

    obj4.name = 'population'
    obj4.index.name = 'state'
    obj4
    """
    state
    California        NaN
    Ohio          35000.0
    Oregon        16000.0
    Texas         71000.0
    Name: population, dtype: float64
    """
    
  • 改变Series的索引:按位置赋值

    In [41]: obj
    Out[41]:
    0     4
    1     7
    2    -5
    3     3
    dtype: int64
    In [42]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
    In [43]: obj
    Out[43]:
    Bob       4
    Steve     7
    Jeff     -5
    Ryan      3
    dtype: int64
    

DataFrame

DataFrame是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)。

DataFrame既有行索引也有列索引,它可以被视为一个共享相同索引的Series的字典。

分层索引是pandas中一种更为高级的数据处理特性。

构建DataFrame

  • 利用等长度列表或NumPy数组的字典来形成DataFrame

    data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'Nevada'],
            'year': [2000, 2001, 2002, 2001, 2002, 2003],
            'pop': [1.5, 1.7,3.6,2.4,2.9,3.2]}
    frame = pd.DataFrame(data)
    frame
    """
    
    state	year	pop
    0	Ohio	2000	1.5
    1	Ohio	2001	1.7
    2	Ohio	2002	3.6
    3	Nevada	2001	2.4
    4	Nevada	2002	2.9
    5	Nevada	2003	3.2
    """
    

一些常用操作

  • 大型DataFrame,head方法会选出头部的五行

  • 指定列顺序后,DataFrame的列将会按照指定顺序排列;列不包含在字典中时,结果会出现缺失值

  • DataFrame中的一列,可以按字典型标记或属性那样检索为Series:frame2['state']frame2.year

    frame2[colunm]对于任意列名均有效,但是frame2.column只在列名是有效的Python变量名时有效

    • 返回的Series与原DataFrame有相同的索引,且Series的name属性也会被合理地设置。
    • 通过位置或特殊属性loc进行选取:frame2.loc['three']
  • 列的引用是可以修改的,例如,空的’debt’列可以赋值为标量值或值数组。

    frame2['debt'] = 16.5
    frame2['debt'] = np.arange(6)
    
  • 将列表或数组赋值给一个列时,值的长度必须和DataFrame的长度相匹配

  • 将Series赋值给一列时,Series的索引将会按照DataFrame的索引重新排列,并在空缺的地方填充缺失值

  • 如果被赋值的列并不存在,则会生成一个新的列

  • del关键字可以删除DataFrame列(像在字典中)

  • 向DataFrame中增加一列

    • # 增加一列布尔值,判断条件是state是否为'ohio'
      frame2['eastern'] = frame2.state == 'Ohio'
      # 注意: frame2.eastern的语法无法创建新的列
      
      # del移除之前新建的列
      del frame2['eastern']
      
  • 从DataFrame中选取的列是数据的视图,而不是拷贝

    对Series的修改会映射到DataFrame中,需要复制显示使用Series的copy方法

包含字典的嵌套字典

  • 将嵌套字典赋值给DataFrame,Pandas会将字典的键作为列,将内部字典的键作为行索引

    pop = {'Nevada': {2001: 2.4, 2002: 2.9}, 'Ohio': {2000: 1.5,2001:1.7,2002:3.6}}
    frame3 = pd.DataFrame(pop)
    frame3
    """
    	Nevada	Ohio
    2001	2.4	1.7
    2002	2.9	3.6
    2000	NaN	1.5
    """
    # 使用类似NumPy语法进行转置操作
    frame3.T
    """
    2001	2002	2000
    Nevada	2.4	2.9	NaN
    Ohio	1.7	3.6	1.5
    """
    # 显示指明索引,内部字典的键不会排序
    pd.DataFrame(pop,index=[2001,2002,2003])
    """
    Nevada	Ohio
    2001	2.4	1.7
    2002	2.9	3.6
    2003	NaN	NaN
    """
    
  • DataFrame构造函数的有效输入

    img
  • DataFrame的索引和列拥有name属性,则这些name属性也会被显示

    frame3.index.name='year'
    frame3.columns.name = 'state'
    frame3
    """
    state	Nevada	Ohio
    year		
    2001	2.4	1.7
    2002	2.9	3.6
    2000	NaN	1.5
    """
    
  • DataFrame的values属性会将包含在DataFrame中的数据以二维ndarray的形式返回

    frame3.values
    """
    array([[2.4, 1.7],
           [2.9, 3.6],
           [nan, 1.5]])
    """
    

    DataFrame的列是不同的dtypes,则values的dtype会自动选择适合所有列的类型

索引对象

用于存储轴标签和其他元数据的(例如轴名称或标签)

构造Series或DataFrame时,你所使用的任意数组或标签序列都可以转换为索引对象

  • 索引对象不可修改,分享更为安全

    obj = pd.Series(range(3),index=['a','b','c'])
    index = obj.index
    index # Index(['a', 'b', 'c'], dtype='object')
    index[1:] # Index(['b', 'c'], dtype='object')
    
  • pandas索引对象是一个固定大小的集合,但是它可以包含重复标签

  • 一些索引对象的方法和属性

    img

5.2 基本功能

重建索引

  • reindex是pandas对象的重要方法,用于创建一个符合新索引的新对象,并进行排列,如果某个索引值之前并不存在,则会引入缺失值。

    import pandas as pd
    obj = pd.Series([4.5,7.2,-5.3,3.6],index=['d','b','a','c'])
    obj
    """
    d    4.5
    b    7.2
    a   -5.3
    c    3.6
    dtype: float64
    """
    obj2 = obj.reindex(['a','b','c','d','e'])
    obj2
    """
    a   -5.3
    b    7.2
    c    3.6
    d    4.5
    e    NaN #如果某个索引值之前并不存在,则会引入缺失值
    dtype: float64
    """
    
  • 重建顺序数据(时间序列等)索引时可能需要进行插值或填值

    • method可选参数可使用ffill等方法在重建索引时插值,向前填充

    • obj3 = pd.Series(['blue','purple','yellow'],index=[0,2,4])
      obj3
      """
      0      blue
      2    purple
      4    yellow
      dtype: object
      """
      obj3.reindex(range(6),method='ffill')
      """
      0      blue
      1      blue
      2    purple
      3    purple
      4    yellow
      5    yellow
      dtype: object
      """
      

DataFrame中的reindex

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

    frame = pd.DataFrame(np.arange(9).reshape((3,3)),
                        index=['a','c','d'],
                        columns=['Ohio','Texas','California'])
    frame
    """
    Ohio	Texas	California
    a	0	1	2
    c	3	4	5
    d	6	7	8
    """
    frame2 = frame.reindex(['a','b','c','d'])
    frame2
    """
    Ohio	Texas	California
    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 = ['Texas','Utah','Califormia']
    frame.reindex(columns=states)
    """
    	Texas	Utah	Califormia
    a	1	NaN	NaN
    c	4	NaN	NaN
    d	7	NaN	NaN
    """
    
  • reindex的index参数:新建作为索引的序列,可以是索引实例或任意其他序列型Python数据结构,索引使用时无须复制

轴向上删除条目

  • drop方法会返回一个含有指示值或轴向上删除值的新对象

    obj = pd.Series(np.arange(5.),index=['a','b','c','d','e'])
    obj
    """
    a    0.0
    b    1.0
    c    2.0
    d    3.0
    e    4.0
    dtype: float64
    """
    obj.drop(['d','c'])
    """
    a    0.0
    b    1.0
    e    4.0
    dtype: float64
    """
    

DataFrame中的drop

  • 调用drop时默认删除行标签(轴0)

    data = pd.DataFrame(np.arange(16).reshape((4, 4)),
                        index=['Ohio', 'Colorado', 'Utah', 'New York'],
                        columns=['one', 'two', 'three', 'four'])
    data
    """
    	one	two	three	four
    Ohio	0	1	2	3
    Colorado	4	5	6	7
    Utah	8	9	10	11
    New York	12	13	14	15
    """
    data.drop(['Colorado','Ohio'])
    """
    
    one	two	three	four
    Utah	8	9	10	11
    New York	12	13	14	15
    """
    # 传递axis=1或axis='columns’来从列中删除值
    data.drop('two',axis=1)
    """
    one	three	four
    Ohio	0	2	3
    Colorado	4	6	7
    Utah	8	10	11
    New York	12	14	15
    """
    
  • drop,会修改Series或DataFrame的尺寸或形状;直接操作原对象而不是返回新对象

  • 【注意】inplace属性:会清除被删除的数据:obj.drop(‘c’,inplace=True)

索引、选择与过滤

  • Series的索引与NumPy数组类似,但是不仅可以索引整数

    obj = pd.Series(np.arange(4.),index=['a','b','c','d'])
    obj
    """
    a    0.0
    b    1.0
    c    2.0
    d    3.0
    dtype: float64
    """
    obj['b'] # 1.0
    obj[2:4]
    """
    c    2.0
    d    3.0
    dtype: float64
    """
    obj[['b','a','d']]
    """
    b    1.0
    a    0.0
    d    3.0
    dtype: float64
    """
    obj[[1,3]]
    """
    b    1.0
    d    3.0
    dtype: float64
    """
    obj[obj<2]
    """
    a    0.0
    b    1.0
    dtype: float64
    """
    
  • Series切片(不同于Python切片)

    • 使用切片修改值会修改Series的相应部分:obj[‘b’ : ‘c’]
    • 使用单个值或序列,可以从DataFrame中索引出一个或多个列
    • 可根据布尔值数组切片选择数据
      • data[:2] # 选前两行
      • data[data[‘three’]>5]
  • 使用布尔值DataFrame进行索引,可以和标量比较产生

    • data < 5 (data是DataFrame类型)
    • data[data<5] = 0 (小于5的数赋值为0)

使用loc和iloc选择数据

DataFrame允许你使用轴标签(loc)或整数标签(iloc)以NumPy风格的语法从DataFrame中选出数组的行和列的子集

  • 示例

    data.loc['Colorado',['two','three']]
    """
    two      5
    three    6
    Name: Colorado, dtype: int32
    """
    # 整数标签iloc进行类似的数据选择
    data.iloc[2,[3,0,1]]
    """
    four    11
    one      8
    two      9
    Name: Utah, dtype: int32
    """
    
  • 所以用于切片

    data.loc[:'Utah','two']
    """
    Ohio        1
    Colorado    5
    Utah        9
    Name: two, dtype: int32
    """
    data.iloc[:,:3][data.three >5]
    """
    one	two	three
    Colorado	4	5	6
    Utah	8	9	10
    New York	12	13	14
    """
    
  • DataFrame索引选项

    epub_22739904_74

整数索引

  • 在pandas对象上使用整数索引会产生歧义,非整数索引不会有潜在的歧义

  • 使用loc(用于标签)或iloc(用于整数)

    ser = pd.Series(np.arange(3.))
    ser
    """
    0    0.0
    1    1.0
    2    2.0
    dtype: float64
    """
    ser[:1] 
    # 0    0.0
    # dtype: float64
    ser.loc[:1]
    """
    0    0.0
    1    1.0
    dtype: float64
    """
    ser.iloc[:1]
    """
    0    0.0
    dtype: float64
    """
    

算术和数据对齐

  • 对象相加时,索引对不相同,返回结果的索引将是索引对的并集,类似于数据库的自动外连接(Outer join)

    s1 = pd.Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
    s2 = pd.Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
    s1 +s2
    """
    a    5.2
    c    1.1
    d    NaN
    e    0.0
    f    NaN
    g    NaN
    dtype: float64
    """
    
  • 将DataFrame对象加在一起,返回一个DataFrame,它的索引、列是每个DataFrame的索引、列的并集。

    • 两个行或列完全不同的DataFrame对象相加,结果将全部为空

使用填充值的算术方法

  • 两个DataFrame对象相加时,一些不重叠的位置会出现NA值,举例:填充0:df1.add(df2,fill_value=0)

  • 灵活算术方法

    epub_22739904_75

    以r开头的副本方法的参数是翻转的,1/df1和df1.rdiv(1)等价

DataFrame和Series间的操作

和NumPy中不同维度数组间的操作类似

  • 考虑二维数组和其中一行的区别,广播机制:减法在每一行都进行了操作(对列进行匹配,并广播到各行

    arr = np.arange(12.).reshape((3,4))
    arr[0] # array([0., 1., 2., 3.])
    arr - arr[0]
    """
    array([[0., 0., 0., 0.],
           [4., 4., 4., 4.],
           [8., 8., 8., 8.]])
    """
    
  • 在列上进行广播,在行上匹配,必须使用算术方法的一种:frame.sub(series3,axis=‘index’),使用axis=‘index’或axis=0

函数应用和映射

  • NumPy的通用函数(逐元素数组方法)对pandas对象也有效:np.abs(frame)

  • DataFrame的apply方法将函数应用到**一行或一列(默认)**的一维数组上

    • 举例

      frame = pd.DataFrame(np.random.randn(4,3),columns=list('bde'),
                          index=['Utah','Ohio','Texas','Oregon'])
      # 函数f,可以计算Series最大值和最小值的差,会被frame中的每一列调用一次
      # 结果是一个以frame的列作为索引的Series
      f =  lambda x:x.max() - x.min()
      frame.apply(f)
      """
      b    3.071398
      d    2.095664
      e    2.016091
      dtype: float64
      """
      # 函数每行被调用一次
      frame.apply(f,axis='columns')
      """
      Utah      2.410035
      Ohio      0.303477
      Texas     0.808933
      Oregon    1.718999
      dtype: float64
      """
      
    • 大部分最常用的数组统计(sum和mean)都是DataFrame的方法,apply不是必需的

    • 传递给apply的不一定要返回一个标量值,也可以返回带有多个值的Series

  • 可以使用逐元素的Python函数,举例:根据frame总的每个浮点数计算一个格式化字符串,可以使用applymap方法

    format = lambda x: '%.2f' % x
    frame.applymap(format)
    """
    b	d	e
    Utah	-0.86	1.53	0.19
    Ohio	0.25	0.46	-1.16
    Texas	-0.59	-0.60	-1.08
    Oregon	-1.09	0.36	-0.19
    """
    

    用applymap作为函数名是因为Series有map方法

    将逐元素应用到Series上:frame[‘e’].map(format)

排序和排名

排序

  • 按行或列索引进行字典型排序,使用sort_index方法,返回一个新的、排序好的对象
    • 默认升序,也可以降序排序:ascending=False
    • 对DataFrame进行排序时,使用一列或多列作为排序键,通过给sort_values的可选参数by实现
      • frame.sort_values(by=‘b’)
      • frame.sort_values(by = [‘a’,’b])
  • 使用sort_values方法根据Series的值进行排序
    • 默认所有的缺失值都会被排序至Series的尾部

排名

排名是指对数组从1到有效数据点总数分配名次的操作

  • Series和DataFrame的rank方法是实现排名的方法。

    • 默认通过平均排名分配到每个组来打破平级关系。

    • 也可以根据他们在数据中的观察顺序进行分配

      • 对条目0和2设置的名次为6和7,而不是之前的平均排名6.5,是因为在数据中标签0在标签2的前面。
    • 按降序排名:obj.rank(ascending=False,method=‘max’)

    • 排名中的平级关系打破方法

      img
    • DataFrame可以对行或列计算排名:frame.rank(axis = ‘columns’)

含有重复标签的轴索引

  • 轴索引并不是强制唯一性,但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
      
    • 有重复索引时,标签索引多个条目会返回一个序列,单个条目会返回标量值

      obj['a']
      """
      a    0
      a    1
      dtype: int64
      """
      obj['c'] # 4
      
    • 重复索引会使代码更复杂,因为来自索引的输出类型可能因标签是否重复而有所不同

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

  • Pandas对象封装了常用数学、统计学方法的集合,大部分属于规约或汇总统计的类别。

    • 从DataFrame的行或列中抽取一个Series或一系列值的单个值(如总和或平均值)

    • 内建了处理缺失值的功能

    • 传入axis='columns’或axis=1,则会将一行上各个列的值相加:df.sum(axis=‘columns’)

    • NA值会被自动排除(除非全都是),可以通过禁用skipna来实现不排除NA值

    • 规约方法可选参数

      img
    • 有一些方法返回间接统计信息:比如最小值或最大值的索引值:比如idxmin和idxmax

  • 积累型方法:df.cumsum()

  • describe方法:一次产生多个汇总统计,既不是规约方法也不是积累型方法。

    • describe方法也可以描述非数值型数据
  • 描述性统计和汇总统计方法

    img

相关性和协方差

  • Series的corr方法计算的是两个Series中重叠的、非NA的、按索引对齐的值的相关性。相应地,cov计算的是协方差。
    • returns[‘MSFT’].corr(returns[‘IBM’])
    • returns.MSFT.corr(returns.IBM),MSFT是一个有效的Python属性
    • 以DataFrame的形式返回相关性和协方差矩阵
  • DataFrame的corrwith方法:DataFrame中的行或列与另一个序列或DataFrame的相关性
    • 传入一个Series时,会返回一个含有为每列计算相关性值的Series
    • 传入一个DataFrame时,会计算匹配到列名的相关性数值
    • 传入axis='columns’会逐行地进行计算

唯一值、计数和成员属性

另一类相关的方法可以从一维Series包含的数值中提取信息

  • unique:给出Series中的唯一值

    import pandas as pd
    obj = pd.Series(['c','a','d','a','a','b','b','c','c'])
    uniques = obj.unique()
    uniques # array(['c', 'a', 'd', 'b'], dtype=object)
    
    • 排序:uniques.sort()
  • 计算Series包含值的个数:value_counts()

    • 按照数量降序排序:pd.value_counts(obj.values,sort=False)
  • isin执行向量化的成员属性检查,将数据集以Series或DataFrame一列的形式过滤为数据集的值子集。

    • 示例

      obj
      """
      0    c
      1    a
      2    d
      3    a
      4    a
      5    b
      6    b
      7    c
      8    c
      dtype: object
      """
      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=int64)
      
  • 唯一值、计数和集合成员属性方法

    img
  • 计算DataFrame多个相关列的直方图

    无标题

    这里,结果中的行标签是所有列中出现的不同值,数值则是这些不同值在每个列中出现的次数。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值