美文网首页
《利用Python进行数据分析》第五章-pandas的数据结构介

《利用Python进行数据分析》第五章-pandas的数据结构介

作者: 龍猫君 | 来源:发表于2017-12-11 20:16 被阅读0次

    pandas的数据结构介绍

    要使用pandas,你首先就得熟悉它的两个主要数据结构:Series和DataFrame。虽然它们并不能解决所有问题,但它们为大多数应用提供了一种可靠的、易于使用的基础。

    In [1]: from pandas import Series,DataFrame
    
    In [2]: import pandas as pd
    
    In [3]: import numpy as np
    

    Series

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

    In [4]: obj=Series([5,8,-6,2])
    
    In [5]: obj
    Out[5]: 
    0 5
    1 8
    2 -6
    3 2
    dtype: int64
    

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

    In [6]: obj.values
    Out[6]: array([ 5, 8, -6, 2], dtype=int64)
    
    In [7]: obj.index
    Out[7]: RangeIndex(start=0, stop=4, step=1)
    

    希望所创建的Series带有一个可以对各个数据点进行标记的索引

    In [8]: obj2=Series([4,8,-6,3],index=['d','a','b','c'])
    
    In [9]: obj2
    Out[9]: 
    d 4
    a 8
    b -6
    c 3
    dtype: int64
    

    与普通NumPy数组相比,你可以通过索引的方式选取Series中的单个或一组值

    In [10]: obj2['b']
    Out[10]: -6
    
    In [11]: obj2['d']=9
    
    In [12]: obj2[['c','a','d']]
    Out[12]: 
    c 3
    a 8
    d 9
    dtype: int64
    

    NumPy数组运算(如根据布尔型数组进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接

    In [13]: obj2
    Out[13]: 
    d 9
    a 8
    b -6
    c 3
    dtype: int64
    
    In [14]: obj2[obj2>0]
    Out[14]: 
    d 9
    a 8
    c 3
    dtype: int64
    
    In [15]: obj2*3
    Out[15]: 
    d 27
    a 24
    b -18
    c 9
    dtype: int64
    
    In [16]: np.exp(obj2)
    Out[16]: 
    d 8103.083928
    a 2980.957987
    b 0.002479
    c 20.085537
    dtype: float64
    

    可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射。它可以用在许多原本需要字典参数的函数中。

    In [17]: 'b' in obj2
    Out[17]: True
    
    In [18]: 'k' in obj2
    Out[18]: False
    

    如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series

    In [19]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}
    
    In [20]: obj3=Series(sdata)
    
    In [21]: obj3
    Out[21]: 
    Ohio 35000
    Oregon 16000
    Texas 71000
    Utah 5000
    dtype: int64
    

    如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列)

    In [22]: states = ['California', 'Ohio', 'Oregon', 'Texas']
    
    In [23]: obj4 = Series(sdata, index=states)
    
    In [24]: obj4
    Out[24]: 
    California NaN
    Ohio 35000.0
    Oregon 16000.0
    Texas 71000.0
    dtype: float64
    

    sdata中跟states索引相匹配的那3个值会被找出来并放到相应的位置上,但由于"California"所对应的sdata值找不到,所以其结果就为NaN(即“非数字”(not a number),在pandas中,它用于表示缺失或NA值)。我将使用缺失(missing)或NA表示缺失数据。pandas的isnull和notnull函数可用于检测缺失数据

    In [25]: pd.isnull(obj4)
    Out[25]: 
    California True
    Ohio False
    Oregon False
    Texas False
    dtype: bool
    
    In [26]: pd.notnull(obj4)
    Out[26]: 
    California False
    Ohio True
    Oregon True
    Texas True
    dtype: bool
    
    In [27]: obj4.isnull()
    Out[27]: 
    California True
    Ohio False
    Oregon False
    Texas False
    dtype: bool
    

    Series最重要的一个功能是:它在算术运算中会自动对齐不同索引的数据。

    In [28]: obj3
    Out[28]: 
    Ohio 35000
    Oregon 16000
    Texas 71000
    Utah 5000
    dtype: int64
    
    In [29]: obj4
    Out[29]: 
    California NaN
    Ohio 35000.0
    Oregon 16000.0
    Texas 71000.0
    dtype: float64
    
    In [30]: obj3+obj4
    Out[30]: 
    California NaN
    Ohio 70000.0
    Oregon 32000.0
    Texas 142000.0
    Utah NaN
    dtype: float64
    

    Series对象本身及其索引都有一个name属性,该属性跟pandas其他的关键功能关系非常密切

    In [31]: obj4.name = 'population'
    
    In [32]: obj4.index.name = 'state'
    
    In [33]: obj4
    Out[33]: 
    state
    California NaN
    Ohio 35000.0
    Oregon 16000.0
    Texas 71000.0
    Name: population, dtype: float64
    
    In [34]: obj
    Out[34]: 
    0 5
    1 8
    2 -6
    3 2
    dtype: int64
    

    Series的索引可以通过赋值的方式就地修改

    In [35]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
    
    In [36]: obj
    Out[36]: 
    Bob 5
    Steve 8
    Jeff -6
    Ryan 2
    dtype: int64
    

    DataFrame

    DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)。
    注意: 虽然DataFrame是以二维结构保存数据的,但你仍然可以轻松地将其表示为更高维度的数据。

    构建DataFrame的办法有很多,最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典。

    In [37]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        ...:         'year': [2000, 2001, 2002, 2001, 2002],
        ...:         'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}
    
    In [38]: frame=DataFrame(data)
    

    结果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列

    In [39]: frame
    Out[39]: 
    pop state year
    0 1.5 Ohio 2000
    1 1.7 Ohio 2001
    2 3.6 Ohio 2002
    3 2.4 Nevada 2001
    4 2.9 Nevada 2002
    

    如果指定了列序列,则DataFrame的列就会按照指定顺序进行排序

    In [40]: DataFrame(data, columns=['year', 'state', 'pop'])
    Out[40]: 
    year state pop
    0 2000 Ohio 1.5
    1 2001 Ohio 1.7
    2 2002 Ohio 3.6
    3 2001 Nevada 2.4
    4 2002 Nevada 2.9
    
    In [41]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
        ...:                       index=['one', 'two', 'three', 'four', 'five'])
    

    跟Series一样,如果传入的列在数据中找不到,就会产生NA值

    In [42]: frame2
    Out[42]: 
    year state pop debt
    one 2000 Ohio 1.5 NaN
    two 2001 Ohio 1.7 NaN
    three 2002 Ohio 3.6 NaN
    four 2001 Nevada 2.4 NaN
    five 2002 Nevada 2.9 NaN
    
    In [43]: frame2.columns
    Out[43]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
    

    通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series

    In [44]: frame2['state']
    Out[44]: 
    one Ohio
    two Ohio
    three Ohio
    four Nevada
    five Nevada
    Name: state, dtype: object
    
    In [45]: frame2.year
    Out[45]: 
    one 2000
    two 2001
    three 2002
    four 2001
    five 2002
    Name: year, dtype: int64
    

    注意,返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。行也可以通过位置或名称的方式进行获取,比如用索引字段ix(被舍弃使用),可以使用loc

    In [46]: frame2.ix['three']
    C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:1: DeprecationWarning: 
    .ix is deprecated. Please use
    .loc for label based indexing or
    .iloc for positional indexing
    
    See the documentation here:
    http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate_ix
    """Entry point for launching an IPython kernel.
    Out[46]: 
    year 2002
    state Ohio
    pop 3.6
    debt NaN
    Name: three, dtype: object
    
    In [47]: frame2.loc['three']
    Out[47]: 
    year 2002
    state Ohio
    pop 3.6
    debt NaN
    Name: three, dtype: object
    

    列可以通过赋值的方式进行修改。例如,我们可以给那个空的"debt"列赋上一个标量值或一组值

    In [48]: frame2['debt'] = 18.5
    
    In [49]: frame2
    Out[49]: 
    year state pop debt
    one 2000 Ohio 1.5 18.5
    two 2001 Ohio 1.7 18.5
    three 2002 Ohio 3.6 18.5
    four 2001 Nevada 2.4 18.5
    five 2002 Nevada 2.9 18.5
    
    In [50]: frame2['debt'] = np.arange(5.)
    
    In [51]: frame2
    Out[51]: 
    year state pop debt
    one 2000 Ohio 1.5 0.0
    two 2001 Ohio 1.7 1.0
    three 2002 Ohio 3.6 2.0
    four 2001 Nevada 2.4 3.0
    five 2002 Nevada 2.9 4.0
    

    将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值

    In [52]: val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
    
    In [53]: frame2['debt']=val
    
    In [54]: frame2
    Out[54]: 
    year state pop debt
    one 2000 Ohio 1.5 NaN
    two 2001 Ohio 1.7 -1.2
    three 2002 Ohio 3.6 NaN
    four 2001 Nevada 2.4 -1.5
    five 2002 Nevada 2.9 -1.7
    

    为不存在的列赋值会创建出一个新列。关键字del用于删除列

    In [55]: frame2['eastern'] = frame2.state == 'Ohio'
    
    In [56]: frame2
    Out[56]: 
    year state pop debt eastern
    one 2000 Ohio 1.5 NaN True
    two 2001 Ohio 1.7 -1.2 True
    three 2002 Ohio 3.6 NaN True
    four 2001 Nevada 2.4 -1.5 False
    five 2002 Nevada 2.9 -1.7 False
    
    In [57]: del frame2['eastern']
    
    In [58]: frame2.columns
    Out[58]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
    

    警告: 通过索引方式返回的列只是相应数据的视图而已,并不是副本。因此,对返回的Series所做的任何就地修改全都会反映到源DataFrame上。通过Series的copy方法即可显式地复制列。
    另一种常见的数据形式是嵌套字典(也就是字典的字典),如果将它传给DataFrame,它就会被解释为:外层字典的键作为列,内层键则作为行索引。

    In [64]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
    In [65]: frame3=DataFrame(pop)
    In [66]: frame3
    Out[66]: 
    Nevada Ohio
    2000 NaN 1.5
    2001 2.4 1.7
    2002 2.9 3.6
    

    对该结果进行转置

    In [67]: frame3.T
    Out[67]: 
    2000 2001 2002
    Nevada NaN 2.4 2.9
    Ohio 1.5 1.7 3.6
    

    内层字典的键会被合并、排序以形成最终的索引。如果显式指定了索引,则不会这样

    In [68]: DataFrame(pop, index=[2001, 2002, 2003])
    Out[68]: 
    Nevada Ohio
    2001 2.4 1.7
    2002 2.9 3.6
    2003 NaN NaN
    

    由Series组成的字典差不多也是一样的用法

    In [69]: pdata = {'Ohio': frame3['Ohio'][:-1],'Nevada': frame3['Nevada'][:2]}
    
    In [70]: DataFrame(pdata)
    Out[70]: 
    Nevada Ohio
    2000 NaN 1.5
    2001 2.4 1.7
    

    表5-1列出了DataFrame构造函数所能接受的各种数据



    如果设置了DataFrame的index和columns的name属性,则这些信息也会被显示出来

    In [71]: frame3.index.name = 'year'; frame3.columns.name = 'state'
    In [72]: frame3
    Out[72]: 
    state Nevada Ohio
    year 
    2000 NaN 1.5
    2001 2.4 1.7
    2002 2.9 3.6
    

    跟Series一样,values属性也会以二维ndarray的形式返回DataFrame中的数据

    In [73]: frame3.values
    Out[73]: 
    array([[ nan, 1.5],
    [ 2.4, 1.7],
    [ 2.9, 3.6]])
    

    如果DataFrame各列的数据类型不同,则值数组的数据类型就会选用能兼容所有列的数据类型

    In [74]: frame2.values
    Out[74]: 
    array([[2000, 'Ohio', 1.5, nan],
    [2001, 'Ohio', 1.7, -1.2],
    [2002, 'Ohio', 3.6, nan],
    [2001, 'Nevada', 2.4, -1.5],
    [2002, 'Nevada', 2.9, -1.7]], dtype=object)
    

    索引对象
    pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index:

    In [75]: obj = Series(range(3), index=['a', 'b', 'c'])
    
    In [76]: obj
    Out[76]: 
    a 0
    b 1
    c 2
    dtype: int32
    
    In [77]: index=obj.index
    
    In [78]: index
    Out[78]: Index(['a', 'b', 'c'], dtype='object')
    
    In [79]: index[1:]
    Out[79]: Index(['b', 'c'], dtype='object')
    

    Index对象是不可修改的(immutable),因此用户不能对其进行修改

    In [80]: index[1]='d'
    ---------------------------------------------------------------------------
    TypeError Traceback (most recent call last)
    <ipython-input-80-d3f90986bdb1> in <module>()
    ----> 1 index[1]='d'
    
    C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\indexes\base.py in __setitem__(self, key, value)
    1618 
    1619 def __setitem__(self, key, value):
    -> 1620 raise TypeError("Index does not support mutable operations")
    1621 
    1622 def __getitem__(self, key):
    
    TypeError: Index does not support mutable operations
    

    不可修改性非常重要,因为这样才能使Index对象在多个数据结构之间安全共享

    In [81]: index = pd.index(np.arange(3))
    ---------------------------------------------------------------------------
    AttributeError Traceback (most recent call last)
    <ipython-input-81-5eb0f1ff3872> in <module>()
    ----> 1 index = pd.index(np.arange(3))
    
    AttributeError: module 'pandas' has no attribute 'index'
    
    In [82]: index = pd.Index(np.arange(3))
    
    In [83]: index
    Out[83]: Int64Index([0, 1, 2], dtype='int64')
    
    In [84]: obj2 = Series([1.5, -3.5, 0], index=index)
    
    In [85]: obj2
    Out[85]: 
    0 1.5
    1 -3.5
    2 0.0
    dtype: float64
    
    In [86]: obj2.index is index
    Out[86]: True
    

    表5-2列出了pandas库中内置的Index类



    除了长得像数组,Index的功能也类似一个固定大小的集合

    In [87]: frame3
    Out[87]: 
    state Nevada Ohio
    year 
    2000 NaN 1.5
    2001 2.4 1.7
    2002 2.9 3.6
    
    In [88]: 'Ohio' in frame3.columns
    Out[88]: True
    
    In [89]: 2003 in frame3.index
    Out[89]: False
    

    每个索引都有一些方法和属性,它们可用于设置逻辑并回答有关该索引所包含的数据的常见问题。表5-3列出了这些函数。


    pandas数据结构的按照书本上进行练习,通过练习操作,可以更好的懂着这些基本的数据结构。

    相关文章

      网友评论

          本文标题:《利用Python进行数据分析》第五章-pandas的数据结构介

          本文链接:https://www.haomeiwen.com/subject/cfjwixtx.html