zoukankan      html  css  js  c++  java
  • pandas教程1:pandas数据结构入门

    pandas是一个用于进行python科学计算的常用库,包含高级的数据结构和精巧的工具,使得在Python中处理数据非常快速和简单。pandas建造在NumPy之上,它使得以NumPy为中心的应用很容易使用。

    pandas为数据提供了一些解决方案:

    • 支持自动或明确的数据对齐的带有标签轴的数据结构。这可以防止由数据不对齐引起的常见错误,并可以处理不同来源的不同索引数据。
    • 整合的时间序列功能。
    • 以相同的数据结构来处理时间序列和非时间序列。
    • 支持传递元数据(坐标轴标签)的算术运算和缩减。
    • 灵活处理丢失数据。
    • 在常用的基于数据的数据库(例如基于SQL)中的合并和其它关系操作。

    对pandas使用下面的导入惯例:

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

    1. pandas数据结构入门

    为了开始使用pandas,你需要熟悉它的两个重要的数据结构: Series 和 DataFrame 。虽然它们不是每一个问题的通用解决方案,但提供了一个坚实的,易于使用的大多数应用程序的基础。

    1.1. Series

    Series是一个一维的类似的数组对象,包含一个数组的数据(任何NumPy的数据类型)和一个与数组关联的数据标签,被叫做 索引 。最简单的Series是由一个数组的数据构成:

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

    通常,需要创建一个带有索引来确定没一个数据点的Series:

    In [5]: obj2 = Series([4, 7, -5, 3], index=['d', 'b', 'a', 'c'])
    In [6]: obj2
    Out[6]:
    d    4
    b    7
    a   -5
    c    3
    dtype: int64
    In [7]: obj2.index
    Out[7]: Index(['d', 'b', 'a', 'c'], dtype='object')
    

    与正规的NumPy数组相比,你可以使用索引里的值来选择一个单一值或一个值集:

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

    NumPy数组操作,例如通过一个布尔数组过滤,纯量乘法,或使用数学函数,将会保持索引和值间的关联:

    In [11]: obj2
    Out[11]:
    d    6
    b    7
    a   -5
    c    3
    dtype: int64
    
    In [12]: obj2[obj2 > 0]
    Out[12]:
    d    6
    b    7
    c    3
    dtype: int64
    
    In [13]: obj2 * 2
    Out[13]:
    d    12
    b    14
    a   -10
    c     6
    dtype: int64
    
    In [19]: np.exp(obj2)
    Out[19]:
    d     403.428793
    b    1096.633158
    a       0.006738
    c      20.085537
    dtype: float64
    

    另一种思考的方式是,Series是一个定长的,有序的字典,因为它把索引和值映射起来了。它可以适用于许多期望一个字典的函数:

    In [20]: 'b' in obj2
    Out[20]: True
    
    In [21]: 'e' in obj2
    Out[21]: False
    

    如果你有一些数据在一个Python字典中,你可以通过传递字典来从这些数据创建一个Series:

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

    只传递一个字典的时候,结果Series中的索引将是排序后的字典的键。

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

    在这种情况下, sdata 中的3个值被放在了合适的位置,但因为没有发现对应于 ‘California’ 的值,就出现了 NaN (不是一个数),这在pandas中被用来标记数据缺失或 NA 值。我使用“missing”或“NA”来表示数度丢失。在pandas中用函数 isnull 和 notnull 来检测数据丢失:

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

    在许多应用中Series的一个重要功能是在算术用算中它会自动对齐不同索引的数据:

    In [30]: obj3
    Out[30]:
    Ohio      35000
    Oregon    16000
    Texas     71000
    Utah       5000
    dtype: int64
    
    In [31]: obj4
    Out[31]:
    California        NaN
    Ohio          35000.0
    Oregon        16000.0
    Texas         71000.0
    dtype: float64
    

    Series对象本身和它的索引都有一个 name 属性,它和pandas的其它一些关键功能整合在一起:

    In [32]: obj4.name = 'population'
    In [33]: obj4.index.name = 'state'
    In [34]: obj4
    Out[34]:
    state
    California        NaN
    Ohio          35000.0
    Oregon        16000.0
    Texas         71000.0
    Name: population, dtype: float64
    

    Series的索引可以通过赋值就地更改:

    In [35]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']
    In [36]: obj
    Out[36]:
    Bob      4
    Steve    7
    Jeff    -5
    Ryan     3
    dtype: int64
    

    1.2. DataFrame

    一个Datarame表示一个表格,类似电子表格的数据结构,包含一个经过排序的列表集,它们每一个都可以有不同的类型值(数字,字符串,布尔等等)。Datarame有行和列的索引;它可以被看作是一个Series的字典(每个Series共享一个索引)。与其它你以前使用过的(如 R 的 data.frame )类似Datarame的结构相比,在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]: DataFrame(data)
    Out[38]:
       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 [39]: DataFrame(data, columns=['year', 'state', 'pop'])
    Out[39]:
       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
    

    和Series一样,如果你传递了一个行,但不包括在 data 中,在结果中它会表示为NA值:

    In [40]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],
        ...: index=['one', 'two', 'three', 'four', 'five'])
    
    In [41]: frame2
    Out[41]:
           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 [42]: frame2.columns
    Out[42]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
    

    和Series一样,在DataFrame中的一列可以通过字典记法或属性来检索:

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

    注意,返回的Series包含和DataFrame相同的索引,并且它们的 name 属性也被正确的设置了。

    行也可以使用一些方法通过位置或名字来检索,例如 ix 索引成员(field):

    In [45]: frame2.ix['three']
    Out[45]:
    year     2002
    state    Ohio
    pop       3.6
    debt      NaN
    Name: three, dtype: object
    

    列可以通过赋值来修改。例如,空的 ‘debt’ 列可以通过一个纯量或一个数组来赋值:

    In [46]: frame2['debt'] = 16.5
    
    In [47]: frame2
    Out[47]:
           year   state  pop  debt
    one    2000    Ohio  1.5  16.5
    two    2001    Ohio  1.7  16.5
    three  2002    Ohio  3.6  16.5
    four   2001  Nevada  2.4  16.5
    five   2002  Nevada  2.9  16.5
    
    In [49]: frame2['debt'] = np.arange(5.)
    
    In [50]: frame2
    Out[50]:
           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 [51]: val = Series([-1.2, -1.5, -1.7], index=['two', 'four', 'five'])
    
    In [52]: frame2['debt'] = val
    
    In [53]: frame2
    Out[53]:
           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 [54]: frame2['eastern'] = frame2.state = 'Ohio'
    
    In [55]: frame2
    Out[55]:
           year state  pop  debt eastern
    one    2000  Ohio  1.5   NaN    Ohio
    two    2001  Ohio  1.7  -1.2    Ohio
    three  2002  Ohio  3.6   NaN    Ohio
    four   2001  Ohio  2.4  -1.5    Ohio
    five   2002  Ohio  2.9  -1.7    Ohio
    
    In [56]: del frame2['eastern']
    
    In [57]: frame2.columns
    Out[57]: Index(['year', 'state', 'pop', 'debt'], dtype='object')
    

    索引DataFrame时返回的列是底层数据的一个视窗,而不是一个拷贝。因此,任何在Series上的就地修改都会影响DataFrame。列可以使用Series的 copy 函数来显式的拷贝。

    另一种通用的数据形式是一个嵌套的字典的字典格式:

    In [58]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},
        ...: 'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}
    

    如果被传递到DataFrame,它的外部键会被解释为列索引,内部键会被解释为行索引:

    In [59]: frame3 = DataFrame(pop)
    
    In [60]: frame3
    Out[60]:
          Nevada  Ohio
    2000     NaN   1.5
    2001     2.4   1.7
    2002     2.9   3.6
    

    当然,你总是可以对结果转置:

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

    内部字典的键被结合并排序来形成结果的索引。如果指定了一个特定的索引,就不是这样的了:

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

    Series的字典也以相同的方式来处理:

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

    如果一个DataFrame的 index 和 columns 有它们的 name ,也会被显示出来:

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

    像Series一样, values 属性返回一个包含在DataFrame中的数据的二维ndarray:

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

    如果DataFrame的列有不同的dtypes,返回值数组将会给所有的列选择一个合适的dtyps:

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

    可能的传递到DataFrame的构造器

    二维ndarray 一个数据矩阵,有可选的行标和列标
    数组,列表或元组的字典 每一个序列成为DataFrame中的一列。所有的序列必须有相同的长度。
    NumPy的结构/记录数组 和“数组字典”一样处理
    Series的字典 每一个值成为一列。如果没有明显的传递索引,将结合每一个Series的索引来形成结果的行索引。
    字典的字典 每一个内部的字典成为一列。和“Series的字典”一样,结合键值来形成行索引。
    字典或Series的列表 每一项成为DataFrame中的一列。结合字典键或Series索引形成DataFrame的列标。
    列表或元组的列表 和“二维ndarray”一样处理
    另一个DataFrame DataFrame的索引将被使用,除非传递另外一个
    NumPy伪装数组(MaskedArray) 除了蒙蔽值在DataFrame中成为NA/丢失数据之外,其它的和“二维ndarray”一样

    1.3. 索引对象

    pandas的索引对象用来保存坐标轴标签和其它元数据(如坐标轴名或名称)。构建一个Series或DataFrame时任何数组或其它序列标签在内部转化为索引:

    In [70]: obj = Series(range(3), index=['a', 'b', 'c'])
    
    In [71]: index = obj.index
    
    In [72]: index
    Out[72]: Index(['a', 'b', 'c'], dtype='object')
    
    In [73]: index[1:]
    Out[73]: Index(['b', 'c'], dtype='object')
    

    索引对象是不可变的,因此不能由用户改变:

    In [74]: index[1] = 'd'
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-74-676fdeb26a68> in <module>()
    ----> 1 index[1] = 'd'
    
    c:userswangappdatalocalprogramspythonpython36libsite-packagespandasindexesase.py in __setitem__(self, key, value)
       1402
       1403     def __setitem__(self, key, value):
    -> 1404         raise TypeError("Index does not support mutable operations")
       1405
       1406     def __getitem__(self, key):
    
    TypeError: Index does not support mutable operations
    

    索引对象的不可变性非常重要,这样它可以在数据结构中结构中安全的共享:

    In [76]: index = pd.Index(np.arange(3))
    
    In [77]: obj2 = Series([1.5, 2.5, 0], index=index)
    
    In [78]: obj2.index is index
    Out[78]: True
    

    通过一些开发努力,索引可以被子类化,来实现特定坐标轴索引功能。

    多数用户不必要知道许多索引对象的知识,但是它们仍然是pandas数据模型的重要部分。

    pandas中的主要索引对象

    索引 说明
    Index 最通用的索引对象,使用Python对象的NumPy数组来表示坐标轴标签。
    Int64Index 对整形值的特化索引。
    MultiIndex “分层”索引对象,表示单个轴的多层次的索引。可以被认为是类似的元组的数组。
    DatetimeIndex 存储纳秒时间戳(使用NumPy的datetime64 dtyppe来表示)。
    PeriodIndex 对周期数据(时间间隔的)的特化索引。

    除了类似于阵列,索引也有类似固定大小集合一样的功能:

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

    每个索引都有许多关于集合逻辑的方法和属性,且能够解决它所包含的数据的常见问题。

    索引方法和属性

    方法和属性 解决的问题
    append 链接额外的索引对象,产生一个新的索引
    diff 计算索引的差集
    intersection 计算交集
    union 计算并集
    isin 计算出一个布尔数组表示每一个值是否包含在所传递的集合里
    delete 计算删除位置i的元素的索引
    drop 计算删除所传递的值后的索引
    insert 计算在位置i插入元素后的索引
    is_monotonic 返回True,如果每一个元素都比它前面的元素大或相等
    is_unique 返回True,如果索引没有重复的值
    unique 计算索引的唯一值数组

    参考:http://pda.readthedocs.io/en/latest/chp5.html#

  • 相关阅读:
    Linux常用命令之 查找命令 find —— 细说 -atime,-mtime,-ctime
    centos设置静态ip
    Linux中vim的基本操作
    Linux中/和~的区别
    Linux安装vmtools工具
    关于 [lambda x: x*i for i in range(4)] 理解
    Ubuntu虚拟环境的搭建
    tomcat的中的Apache的apr是个啥东东???
    什么是web资源????
    Handlebars学习第一天
  • 原文地址:https://www.cnblogs.com/xianyue/p/6796816.html
Copyright © 2011-2022 走看看