• pandas Series和DataFrame数据类型


    一、Series

    Pandas的核心是三大数据结构:Series、DataFrame和Index。绝大多数操作都是围绕这三种结构进行的。

    Series是一个一维的数组对象,它包含一个值序列和一个对应的索引序列。 Numpy的一维数组通过隐式定义的整数索引获取元素值,而Series用一种显式定义的索引与元素关联。显式索引让Series对象拥有更强的能力,索引也不再仅仅是整数,还可以是别的类型,比如字符串,索引也不需要连续,也可以重复,自由度非常高。

    最基本的生成方式是使用Series构造器:

    import pandas as pd
    s = pd.Series([7,-3,4,-2])
    s
    Out[5]:
    0    7
    1   -3
    2    4
    3   -2
    dtype: int64

    打印的时候,自动对齐了,看起来比较美观。左边是索引,右边是实际对应的值。默认的索引是0到N-1(N是数据的长度)。可以通过values和index属性分别获取Series对象的值和索引:

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

    可以在创建Series对象的时候指定索引:

    In [8]: s2 = pd.Series([7,-3,4,-2], index=['d','b','a','c'])
    In [9]: s2
    Out[9]:
    d    7
    b   -3
    a    4
    c   -2
    dtype: int64
    In [10]: s2.index
    Out[10]: Index(['d', 'b', 'a', 'c'], dtype='object')
    In [4]: pd.Series(5, index=list('abcde'))
    Out[4]:
    a    5
    b    5
    c    5
    d    5
    e    5
    dtype: int64
    In [5]: pd.Series({2:'a',1:'b',3:'c'}, index=[3,2]) # 通过index筛选结果
    Out[5]:
    3    c
    2    a
    dtype: object

    也可以在后期,直接修改index:

    In [33]: s
    Out[33]:
    0    7
    1   -3
    2    4
    3   -2
    dtype: int64
    In [34]: s.index = ['a','b','c','d']
    In [35]: s
    Out[35]:
    a    7
    b   -3
    c    4
    d   -2
    dtype: int64

    类似Python的列表和Numpy的数组,Series也可以通过索引获取对应的值:

    In [11]: s2['a']
    Out[11]: 4
    In [12]: s2[['c','a','d']]
    Out[12]:
    c   -2
    a    4
    d    7
    dtype: int64

    也可以对Seires执行一些类似Numpy的通用函数操作:

    In [13]: s2[s2>0]
    Out[13]:
    d    7
    a    4
    dtype: int64
    In [14]: s2*2
    Out[14]:
    d    14
    b    -6
    a     8
    c    -4
    dtype: int64
    In [15]: import numpy as np
    In [16]: np.exp(s2)
    Out[16]:
    d    1096.633158
    b       0.049787
    a      54.598150
    c       0.135335
    dtype: float64

    因为索引可以是字符串,所以从某个角度看,Series又比较类似Python的有序字典,所以可以使用in操作:

    In [17]: 'b' in s2
    Out[17]: True
    In [18]: 'e'in s2
    Out[18]: False

    自然,我们也会想到使用Python的字典来创建Series:

    In [19]: dic = {'beijing':35000,'shanghai':71000,'guangzhou':16000,'shenzhen':5000}
    In [20]: s3=pd.Series(dic)
    In [21]: s3
    Out[21]:
    beijing      35000
    shanghai     71000
    guangzhou    16000
    shenzhen     5000
    dtype: int64
    In [14]: s3.keys() # 自然,具有类似字典的方法
    Out[14]: Index(['beijing', 'shanghai', 'guangzhou', 'shenzhen'], dtype='object')
    In [15]: s3.items()
    Out[15]: <zip at 0x1a5c2d88c88>
    In [16]: list(s3.items())
    Out[16]:
    [('beijing', 35000),
     ('shanghai', 71000),
     ('guangzhou', 16000),
     ('shenzhen', 5000)]
    In [18]: s3['changsha'] = 20300

    看下面的例子:

    In [22]: city = ['nanjing', 'shanghai','guangzhou','beijing']
    In [23]: s4=pd.Series(dic, index=city)
    In [24]: s4
    Out[24]:
    nanjing          NaN
    shanghai     71000.0
    guangzhou    16000.0
    beijing      35000.0
    dtype: float64

    city列表中,多了‘nanjing’,但少了‘shenzhen’。Pandas会依据city中的关键字去dic中查找对应的值,因为dic中没有‘nanjing’,这个值缺失,所以以专门的标记值NaN表示。因为city中没有‘shenzhen’,所以在s4中也不会存在‘shenzhen’这个条目。可以看出,索引很关键,在这里起到了决定性的作用。

    在Pandas中,可以使用isnull和notnull函数来检查缺失的数据:

    In [25]: pd.isnull(s4)
    Out[25]:
    nanjing       True
    shanghai     False
    guangzhou    False
    beijing      False
    dtype: bool
    In [26]: pd.notnull(s4)
    Out[26]:
    nanjing      False
    shanghai      True
    guangzhou     True
    beijing       True
    dtype: bool
    In [27]: s4.isnull()
    Out[27]:
    nanjing       True
    shanghai     False
    guangzhou    False
    beijing      False
    dtype: bool

    可以为Series对象和其索引设置name属性,这有助于标记识别:

    In [29]: s4.name = 'people'
    In [30]: s4.index.name= 'city'
    In [31]: s4
    Out[31]:
    city
    nanjing          NaN
    shanghai     71000.0
    guangzhou    16000.0
    beijing      35000.0
    Name: people, dtype: float64
    In [32]: s4.index
    Out[32]: Index(['nanjing', 'shanghai', 'guangzhou', 'beijing'], dtype='object', name='city')

    二、DataFrame

    DataFrame是Pandas的核心数据结构,表示的是二维的矩阵数据表,类似关系型数据库的结构,每一列可以是不同的值类型,比如数值、字符串、布尔值等等。DataFrame既有行索引,也有列索引,它可以被看做为一个共享相同索引的Series的字典。

    创建DataFrame对象的方法有很多,最常用的是利用包含等长度列表或Numpy数组的字典来生成。可以查看DataFrame对象的columns和index属性。

    In [37]: data = {'state':['beijing','beijing','beijing','shanghai','shanghai','shanghai'],
        ...: 'year':[2000,2001,2002,2001,2002,2003],
        ...: 'pop':[1.5, 1.7,3.6,2.4,2.9,3.2
        ...: ]}
    In [38]: f = pd.DataFrame(data)
    In [39]: f
    Out[39]:
          state  year  pop
    0   beijing  2000  1.5
    1   beijing  2001  1.7
    2   beijing  2002  3.6
    3  shanghai  2001  2.4
    4  shanghai  2002  2.9
    5  shanghai  2003  3.2
    In [61]: f.columns
    Out[61]: Index(['state', 'year', 'pop'], dtype='object')
    In [62]: f.index
    Out[62]: RangeIndex(start=0, stop=6, step=1)
    In [10]: f.dtypes
    Out[10]:
    state     object
    year       int64
    pop      float64
    dtype: object
    In [11]: f.values  # 按行查看
    Out[11]:
    array([['beijing', 2000, 1.5],
           ['beijing', 2001, 1.7],
           ['beijing', 2002, 3.6],
           ['shanghai', 2001, 2.4],
           ['shanghai', 2002, 2.9],
           ['shanghai', 2003, 3.2]], dtype=object)

     上面自动生成了0-5的索引。

    可以使用head方法查看DataFrame对象的前5行,用tail方法查看后5行。或者head(3),tail(3)指定查看行数:

    In [40]: f.head()
    Out[40]:
          state  year  pop
    0   beijing  2000  1.5
    1   beijing  2001  1.7
    2   beijing  2002  3.6
    3  shanghai  2001  2.4
    4  shanghai  2002  2.9
    In [41]: f.tail()
    Out[41]:
          state  year  pop
    1   beijing  2001  1.7
    2   beijing  2002  3.6
    3  shanghai  2001  2.4
    4  shanghai  2002  2.9
    5  shanghai  2003  3.2

    DataFrame对象中的state/year/pop,其实就是列索引,可以在创建的时候使用参数名columns指定它们的先后顺序:

    In [44]: pd.DataFrame(data, columns=['year','state','pop'])
    Out[44]:
       year     state  pop
    0  2000   beijing  1.5
    1  2001   beijing  1.7
    2  2002   beijing  3.6
    3  2001  shanghai  2.4
    4  2002  shanghai  2.9
    5  2003  shanghai  3.2

    当然,也可以使用参数名index指定行索引:

    In [45]: f2 = pd.DataFrame(data, columns=['year','state','pop'],index=['a','b','c','d','e','f'])
    In [47]: f2
    Out[47]:
       year     state  pop
    a  2000   beijing  1.5
    b  2001   beijing  1.7
    c  2002   beijing  3.6
    d  2001  shanghai  2.4
    e  2002  shanghai  2.9
    f  2003  shanghai  3.2

    可以使用columns列索引来检索一列:

    In [49]: f2['year']
    Out[49]:
    a    2000
    b    2001
    c    2002
    d    2001
    e    2002
    f    2003
    Name: year, dtype: int64
    In [52]: f2.state  # 属性的形式来检索。这种方法bug多,比如属性名不是纯字符串,或者与其它方法同名
    Out[52]:
    a     beijing
    b     beijing
    c     beijing
    d    shanghai
    e    shanghai
    f    shanghai
    Name: state, dtype: object

    但是检索一行却不能通过f2['a']这种方式,而是需要通过loc方法进行选取:

    In [53]: f2.loc['a']
    Out[53]:
    year        2000
    state    beijing
    pop          1.5
    Name: a, dtype: object

    当然,可以给DataFrame对象追加列:

    In [54]: f2['debt'] = 12
    In [55]: f2
    Out[55]:
       year     state  pop  debt
    a  2000   beijing  1.5    12
    b  2001   beijing  1.7    12
    c  2002   beijing  3.6    12
    d  2001  shanghai  2.4    12
    e  2002  shanghai  2.9    12
    f  2003  shanghai  3.2    12
    In [56]: f2['debt'] = np.arange(1,7)
    In [57]: f2
    Out[57]:
       year     state  pop  debt
    a  2000   beijing  1.5     1
    b  2001   beijing  1.7     2
    c  2002   beijing  3.6     3
    d  2001  shanghai  2.4     4
    e  2002  shanghai  2.9     5
    f  2003  shanghai  3.2     6
    In [58]: val = pd.Series([1,2,3],index = ['c','d','f'])
    In [59]: f2['debt'] = val
    In [60]: f2  # 缺失值以NaN填补
    Out[60]:
       year     state  pop  debt
    a  2000   beijing  1.5   NaN
    b  2001   beijing  1.7   NaN
    c  2002   beijing  3.6   1.0
    d  2001  shanghai  2.4   2.0
    e  2002  shanghai  2.9   NaN
    f  2003  shanghai  3.2   3.0

    那么如何给DataFrame追加行呢?

    >>> data = {'state':['beijing','beijing','beijing','shanghai','shanghai','shanghai'],
        ...: 'year':[2000,2001,2002,2001,2002,2003],
        ...: 'pop':[1.5, 1.7,3.6,2.4,2.9,3.2
        ...: ]}
    >>> df = pd.DataFrame(data,index=list('abcdef'))
    >>> df
        state   year    pop
    a   beijing 2000    1.5
    b   beijing 2001    1.7
    c   beijing 2002    3.6
    d   shanghai    2001    2.4
    e   shanghai    2002    2.9
    f   shanghai    2003    3.2
    >>> df1 = df.loc['a']
    >>> df1
    state    beijing
    year        2000
    pop          1.5
    Name: a, dtype: object
    >>> df.append(df1)
    state   year    pop
    a   beijing 2000    1.5
    b   beijing 2001    1.7
    c   beijing 2002    3.6
    d   shanghai    2001    2.4
    e   shanghai    2002    2.9
    f   shanghai    2003    3.2
    a   beijing 2000    1.5

    可以使用del方法删除指定的列:

    In [63]: f2['new'] = f2.state=='beijing'
    In [64]: f2
    Out[64]:
       year  state  pop  debt    new
    a  2000   beijing  1.5   NaN   True
    b  2001   beijing  1.7   NaN   True
    c  2002   beijing  3.6   1.0    True
    d  2001  shanghai  2.4   2.0   False
    e  2002  shanghai  2.9   NaN  False
    f  2003  shanghai  3.2   3.0   False
    In [65]: del f2.new   # 要注意的是我们有时候不能这么调用f2的某个列,并执行某个操作。这是个坑。
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-65-03e4ec812cdb> in <module>()
    ----> 1 del f2.new
    AttributeError: new
    In [66]: del f2['new']
    In [67]: f2.columns
    Out[67]: Index(['year', 'state', 'pop', 'debt'], dtype='object')

    需要注意的是:从DataFrame中选取的列是数据的视图,而不是拷贝。因此,对选取列的修改会反映到DataFrame上。如果需要复制,应当使用copy方法。

    可以使用类似Numpy的T属性,将DataFrame进行转置:

    In [68]: f2.T
    Out[68]:
               a       b        c         d         e        f
    year      2000     2001       2002        2001        2002      2003
    state  beijing  beijing  beijing  shanghai  shanghai  shanghai
    pop        1.5      1.7       3.6         2.4          2.9       3.2
    debt       NaN     NaN     1            2           NaN         3

    DataFrame对象同样具有列名、索引名,也可以查看values:

    In [70]: f2.index.name = 'order';f2.columns.name='key'
    In [71]: f2
    Out[71]:
    key    year     state  pop  debt
    order
    a      2000   beijing  1.5   NaN
    b      2001   beijing  1.7   NaN
    c      2002   beijing  3.6   1.0
    d      2001  shanghai  2.4   2.0
    e      2002  shanghai  2.9   NaN
    f      2003  shanghai  3.2   3.0
    In [72]: f2.values
    Out[72]:
    array([[2000, 'beijing', 1.5, nan],
           [2001, 'beijing', 1.7, nan],
           [2002, 'beijing', 3.6, 1.0],
           [2001, 'shanghai', 2.4, 2.0],
           [2002, 'shanghai', 2.9, nan],
           [2003, 'shanghai', 3.2, 3.0]], dtype=object)

    最后,DataFrame有一个Series所不具备的方法,那就是info!通过这个方法,可以看到DataFrame的一些整体信息情况:

    In [73]: f.info()
    Out[73]:
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 6 entries, 0 to 5
    Data columns (total 3 columns):
    state    6 non-null object
    year     6 non-null int64
    pop      6 non-null float64
    dtypes: float64(1), int64(1), object(1)
    memory usage: 224.0+ bytes
  • 相关阅读:
    A1151 LCA in a Binary Tree (30分)
    A1150 Travelling Salesman Problem (25分)
    A1069 The Black Hole of Numbers (20分)
    A1149 Dangerous Goods Packaging (25分)
    A1148 Werewolf
    A1147 Heaps (30分)
    Ubuntu下git,gitlab团队协作
    如何查看JDK_API 2019.2.23
    linux_day1 (腾老师)2019年3月25日18:11:43(CentOs)
    jpa_缓存
  • 原文地址:https://www.cnblogs.com/lavender1221/p/12664641.html
Copyright © 2020-2023  润新知