• 又见Python<4>:Pandas之DataFrame对象的使用


    Pandas有两大数据结构:Series和DataFrame,之前已对Series对象进行了介绍(链接),本文主要对DataFrame对象的常用用法进行总结梳理。

    约定:

    import pandas as pd
    

    1、什么是DataFrame对象?

    一个二维表,有行索引(index)和列索引(columns),列的数据类型可以不同。


    2、DataFrame对象的创建

    DataFrame对象的创建主要是使用pd.DataFrame方法。主要包括以下三种:

    (1)方法1:通过等长列表组成的字典创建

    df1 = pd.DataFrame({'a':[1,2,3,4],'b':['w','x','y','z']})
    df1
    Out[205]:
       a  b
    0  1  w
    1  2  x
    2  3  y
    3  4  z
    

    (2)方法2:通过嵌套字典创建

    外层字典的键作为列索引,内层字典的键作为行索引。

    df2 = pd.DataFrame({'a':{1:11,2:22,3:33},'b':{1:111,2:222,3:333,4:444}})
    df2
    Out[206]:
          a    b
    1  11.0  111
    2  22.0  222
    3  33.0  333
    4   NaN  444
    

    (3)方法3:通过numpy数组创建

    注意传入DataFrame对象的形状。

    df3 = pd.DataFrame(np.arange(12).reshape(4,3))
    df3
    Out[211]:
       0   1   2
    0  0   1   2
    1  3   4   5
    2  6   7   8
    3  9  10  11
    

    ##3、DataFrame对象的五个主要属性 DataFrame对象的五个主要属性:索引、值、名称、数据类型、形状。 ###(1)索引 **a. 索引的查看** **行**索引使用**index属性**,**列**索引使用**columns属性**,返回Index对象。
    df1.index
    Out[212]: RangeIndex(start=0, stop=4, step=1)
    df1.columns
    Out[213]: Index([u'a', u'b'], dtype='object')
    

    索引可以有重复的,判断是否有重复索引,使用Index对象的is_unique属性判断。

    df1.index.is_unique
    Out[215]: True
    

    b. 索引的修改
    索引对象是一个不可变数组,不能修改其中的值。

    df1.index[1]=5
    Traceback (most recent call last):
      File "<ipython-input-217-360108374774>", line 1, in <module>
        df1.index[1]=5
      File "/usr/local/share/anaconda2/lib/python2.7/site-packages/pandas/indexes/base.py", line 1404, in __setitem__
        raise TypeError("Index does not support mutable operations")
    TypeError: Index does not support mutable operations
    

    如果想修改索引,只能将其重定向到一个新的索引对象。

    df1.index=[5,6,7,8]
    df1
    Out[221]:
       a  b
    5  1  w
    6  2  x
    7  3  y
    8  4  z
    

    c. 索引的重排
    使用reindex方法进行索引重排。通过index参数或者columns参数来区分是对行索引重排还是对列索引重排。重排产生一个新DataFrame对象。

    df1.reindex(index=[6,8,5,7])
    Out[222]:
       a  b
    6  2  x
    8  4  z
    5  1  w
    7  3  y
    df1.reindex(columns=['b','a'])
    Out[223]:
       b  a
    5  w  1
    6  x  2
    7  y  3
    8  z  4
    

    可同时进行行、列索引的重排。

    df1.reindex(index=[6,8,5,7],columns=['b','a'])
    Out[224]:
       b  a
    6  x  2
    8  z  4
    5  w  1
    7  y  3
    

    索引重排可实现3个目的:
    ① 对现有索引进行顺序指定,即重新排列原来的元素顺序;
    ② 删除某个旧索引,即删除对应元素;

    df1.reindex(index=[6,8,7])
    Out[225]:
       a  b
    6  2  x
    8  4  z
    7  3  y
    

    ③ 增加某个新索引,即增加新元素,值为NaN。

    df1.reindex(index=[6,8,5,7,9])
    Out[226]:
         a    b
    6  2.0    x
    8  4.0    z
    5  1.0    w
    7  3.0    y
    9  NaN  NaN
    

    d. 索引的排序
    使用sort_index方法根据索引进行升序、降序排列。
    axis参数指定排序的方向:行内排序列内排序。默认axis=0,列内排序;axis=1,行内排序。

    df4 = pd.DataFrame({'c':[11,33,22,44],'b':['w','x','y','z'],'a':[1,2,3,4]},index=[3,5,2,1],columns=['b','c','a'])
    df4
    Out[229]:
       b   c  a
    3  w  11  1
    5  x  33  2
    2  y  22  3
    1  z  44  4
    df4.sort_index()
    Out[231]:
       b   c  a
    1  z  44  4
    2  y  22  3
    3  w  11  1
    5  x  33  2
    df4.sort_index(axis=1)
    Out[232]:
       a  b   c
    3  1  w  11
    5  2  x  33
    2  3  y  22
    1  4  z  44
    

    ascending参数指定升降序,取值为True或False,默认为True,升序排列。
    e. 索引是否存在
    使用in判断某索引是否存在。

    2 in df1['b']
    Out[292]: True
    

    (2)值

    a. 值的查看
    通过DataFrame对象的values属性获取元素的值,返回一个Numpy数组。

    df1.values
    Out[233]:
    array([[1, 'w'],
           [2, 'x'],
           [3, 'y'],
           [4, 'z']], dtype=object)
    

    b. 值的修改
    无法通过赋值对某一个元素进行取值就改。

    df1.values[1][1]='a'
    df1
    Out[243]:
       a  b
    0  1  w
    1  2  x
    2  3  y
    3  4  z
    

    只能对一行或者一列进行修改。

    df1['a']=55
    df1['b']=range(4)
    df1
    Out[245]:
        a  b
    0  55  0
    1  55  1
    2  55  2
    3  55  3
    

    c. 值的排序
    使用sort_values方法根据值进行升序、降序排列。
    by参数指定排序的行列索引名,可按照多个索引进行排序,传入列表即可,索引顺序即为排序优先级。

    df4.sort_values(by='c')
    Out[250]:
       b   c  a
    3  w  11  1
    2  y  22  3
    5  x  33  2
    1  z  44  4
    df4.sort_values(by=['c','a'])
    Out[251]:
       b   c  a
    3  w  11  1
    2  y  22  3
    5  x  33  2
    1  z  44  4
    

    axis参数指定排序的方向:行内排序列内排序,默认axis=0,列内排序,axis=1,行内排序。

    df4.sort_values(by=3,axis=1)
    Out[252]:
       a   c  b
    3  1  11  w
    5  2  33  x
    2  3  22  y
    1  4  44  z
    

    ascending参数指定升降序,取值为True或False,默认为True,升序排列。
    d. 值的排名
    使用rank方法,对于并列排名,默认取其均值。

    df4.rank()
    Out[253]:
         b    c    a
    3  1.0  1.0  1.0
    5  2.0  3.0  2.0
    2  3.0  2.0  3.0
    1  4.0  4.0  4.0
    

    可通过设置axis参数,指定排名方向,默认列内排名,即axis=0,axis=1,行内排名。

    df4.rank(axis=1)
    Out[254]:
         b    c    a
    3  3.0  2.0  1.0
    5  3.0  2.0  1.0
    2  3.0  2.0  1.0
    1  3.0  2.0  1.0
    

    ascending参数指定升降序,取值为True或False,默认为True,升序排列。
    e. 值是否存在
    使用isin方法判断,要求传入一个列表,返回一个布尔型Series对象。

    df1['b'].isin([2])
    Out[294]:
    0    False
    1    False
    2     True
    3    False
    4    False
    Name: b, dtype: bool
    

    (3)名称

    DataFrame对象的索引对象有名称属性。
    但是DataFrame对象没有名称属性。

    df4.name
    Traceback (most recent call last):
      File "<ipython-input-255-6af278e0d702>", line 1, in <module>
        df4.name
      File "/usr/local/share/anaconda2/lib/python2.7/site-packages/pandas/core/generic.py", line 2744, in __getattr__
        return object.__getattribute__(self, name)
    AttributeError: 'DataFrame' object has no attribute 'name'
    

    (4)数据类型

    通过dtypes属性获取DataFrame对象每列的数据类型。

    df4.dtypes
    Out[257]:
    b    object
    c     int64
    a     int64
    dtype: object
    

    (5)形状

    通过shape属性获取DataFrame对象的形状,返回值为一个元组。

    df4.shape
    Out[258]: (4, 3)
    

    ##4、元素的操作 ###(1)元素选取 **a. 选取行** **选取一行:** ① 按索引名称选取:使用loc[索引名称]
    df4.loc[1]
    Out[261]:
    b     z
    c    44
    a     4
    Name: 1, dtype: object
    

    ② 按索引位置序号选取:使用iloc[索引位置序号]

    df4.iloc[1]
    Out[262]:
    b     x
    c    33
    a     2
    Name: 5, dtype: object
    

    选取多行:
    ① 按索引名称(列表)选取:使用loc[索引名称列表]

    df4.loc[[1,3]]
    Out[263]:
       b   c  a
    1  z  44  4
    3  w  11  1
    

    ② 按索引位置序号(切片)选取:使用iloc[索引位置序号切片]

    df4.iloc[1:3]
    Out[265]:
       b   c  a
    5  x  33  2
    2  y  22  3
    

    b.选取列
    选取一列:
    直接使用索引名称。

    df4['a']
    Out[267]:
    3    1
    5    2
    2    3
    1    4
    Name: a, dtype: int64
    

    选取多列:
    直接使用索引名称组成的列表。

    df4[['a','b']]
    Out[268]:
       a  b
    3  1  w
    5  2  x
    2  3  y
    1  4  z
    

    c. 同时选取行和列
    ① 按索引名称选取:使用loc[行索引名称列表,列索引名称列表]。

    df4.loc[[1,3],['a','b']]
    Out[269]:
       a  b
    1  4  z
    3  1  w
    

    ② 按索引位置序号选取:使用iloc[行索引位置序号切片,列索引位置序号切片]

    df4.iloc[1:3,0:1]
    Out[270]:
       b
    5  x
    2  y
    

    (2)元素过滤

    可直接使用基于值的比较运算条件产生的布尔型数组进行过滤。

    df1>2
    Out[272]:
          a      b
    0  True  False
    1  True  False
    2  True  False
    3  True   True
    df1[df1>2]
    Out[273]:
        a    b
    0  55  NaN
    1  55  NaN
    2  55  NaN
    3  55  3.0
    

    (3)元素新增

    a. 方法1:通过赋值新增

    df1['c']=20
    df1
    Out[275]:
        a  b   c
    0  55  0  20
    1  55  1  20
    2  55  2  20
    3  55  3  20
    

    b. 方法2:通过索引重排新增

    df1=df1.reindex(index=[0,1,2,3,4])
    df1
    Out[277]:
          a    b     c
    0  55.0  0.0  20.0
    1  55.0  1.0  20.0
    2  55.0  2.0  20.0
    3  55.0  3.0  20.0
    4   NaN  NaN   NaN
    

    (4)元素删除

    使用drop方法通过删除指定索引来删除元素。
    通过axis参数确定是删除行还是删除列,默认删除行。
    a. 一次删除一行/列

    df1.drop(1)
    Out[280]:
          a    b     c
    0  55.0  0.0  20.0
    2  55.0  2.0  20.0
    3  55.0  3.0  20.0
    4   NaN  NaN   NaN
    

    b. 一次删除多行/列

    df1.drop(['a','c'],axis=1)
    Out[281]:
         b
    0  0.0
    1  1.0
    2  2.0
    3  3.0
    4  NaN
    

    注意:传入的索引值要与选定的axis方向一致。

    (5)算术运算

    DataFrame对象支持直接进行算术运算。

    df2+2
    Out[283]:
          a    b
    1  13.0  113
    2  24.0  224
    3  35.0  335
    4   NaN  446
    

    (6)判断是否有空值

    使用isnull或者notnull方法判断是否有空值,返回一个布尔型DataFrame对象。

    df1.isnull()
    Out[297]:
           a      b      c
    0  False  False  False
    1  False  False  False
    2  False  False  False
    3  False  False  False
    4   True   True   True
    df1.notnull()
    Out[298]:
           a      b      c
    0   True   True   True
    1   True   True   True
    2   True   True   True
    3   True   True   True
    4  False  False  False
    

    (7)缺失值处理

    缺失值的处理主要有两种方法:填充和过滤。
    a.填充
    使用fillna方法进行空值填充,该方法产生新对象,不会修改原对象。

    df2=df2.reindex(index=[1,2,3,4,5])
    df2
    Out[304]:
          a      b
    1  11.0  111.0
    2  22.0  222.0
    3  33.0  333.0
    4   NaN  444.0
    5   NaN    NaN
    df2.fillna(99)
    Out[308]:
          a      b
    1  11.0  111.0
    2  22.0  222.0
    3  33.0  333.0
    4  99.0  444.0
    5  99.0   99.0
    

    b.过滤
    使用dropna方法进行空值过滤,该方法产生新对象,不会修改原对象。
    axis参数确定过滤行还是过滤列,默认axis=0过滤行,axis=1过滤列。
    how参数控制过滤标准(有空值就丢弃(any)、全空值才丢弃(all)),默认过滤任何含有缺失值的行/列。

    df2.dropna()
    Out[305]:
          a      b
    1  11.0  111.0
    2  22.0  222.0
    3  33.0  333.0
    df2.dropna(axis=1)
    Out[306]:
    Empty DataFrame
    Columns: []
    Index: [1, 2, 3, 4, 5]
    df2.dropna(how='all')
    Out[307]:
          a      b
    1  11.0  111.0
    2  22.0  222.0
    3  33.0  333.0
    4   NaN  444.0
    

    (8)过滤重复值

    使用duplicated方法返回布尔型Series对象,判断哪些行是重复值。

    df1
    Out[317]:
          a    b     c
    0  55.0  0.0  20.0
    1  55.0  1.0  20.0
    2  55.0  2.0  20.0
    3  55.0  3.0  20.0
    4   NaN  NaN   NaN
    df1.duplicated()
    Out[318]:
    0    False
    1    False
    2    False
    3    False
    4    False
    dtype: bool
    

    使用drop_duplicates方法过滤其中的重复行,不修改原对象,而是产生一个没有重复行的新DataFrame对象。

    df1.drop_duplicates()
    Out[320]:
          a    b     c
    0  55.0  0.0  20.0
    1  55.0  1.0  20.0
    2  55.0  2.0  20.0
    3  55.0  3.0  20.0
    4   NaN  NaN   NaN
    

    默认判断全部列,即所有列都相同才叫重复,也可以指定要判断的一列或者多列(通过传入一个列表)。

    df1.duplicated(['a','c'])
    Out[319]:
    0    False
    1     True
    2     True
    3     True
    4    False
    dtype: bool
    df1.drop_duplicates(['a','c'])
    Out[321]:
          a    b     c
    0  55.0  0.0  20.0
    4   NaN  NaN   NaN
    

    (9)汇总统计

    常规的统计方法:sum(求和)、mean(均值)、cumsum(累计求和)、count(非空计数),按列进行汇总。

    df1.sum()
    Out[322]:
    a    220.0
    b      6.0
    c     80.0
    dtype: float64
    df1.mean()
    Out[324]:
    a    55.0
    b     1.5
    c    20.0
    dtype: float64
    df1.cumsum()
    Out[325]:
           a    b     c
    0   55.0  0.0  20.0
    1  110.0  1.0  40.0
    2  165.0  3.0  60.0
    3  220.0  6.0  80.0
    4    NaN  NaN   NaN
    df1.count()
    Out[323]:
    a    4
    b    4
    c    4
    dtype: int64
    

    使用describe方法直接生成描述性统计结果。
    a. 当元素的数据类型为数值型时,生成的结果包括:均值、最大值、最小值、标准差、元素个数、百分位数。

    df1.describe()
    Out[326]:
              a         b     c
    count   4.0  4.000000   4.0
    mean   55.0  1.500000  20.0
    std     0.0  1.290994   0.0
    min    55.0  0.000000  20.0
    25%    55.0  0.750000  20.0
    50%    55.0  1.500000  20.0
    75%    55.0  2.250000  20.0
    max    55.0  3.000000  20.0
    

    b. 当元素的数据类型为类别型时,生成的结果包括:唯一值个数、最大类别、最大类别频数。

    df5=pd.DataFrame({'a':['s','t','y','r'],'b':['w','x','y','z']})
    df5
    Out[330]:
       a  b
    0  s  w
    1  t  x
    2  y  y
    3  r  z
    df5.describe()
    Out[331]:
            a  b
    count   4  4
    unique  4  4
    top     t  w
    freq    1  1
    

    (10)分组聚合

    使用groupby方法产生一个GroupBy对象,然后使用聚合函数(mean、sum等)进行聚合计算。
    groupby方法中传入划分组的一列或者多列。

    df1.groupby('a').sum()
    Out[337]:
            b     c
    a              
    55.0  6.0  80.0
    

    ##5、DataFrame对象之间的操作 ###(1)算术运算 通过+、-、*、等运算符或者add、sub、mul、div等方法进行两个DataFrame对象之间的算术运算。 运算时,行、列索引同时对齐,对应元素进行算术运算,没有重叠的位置,运算结果为NaN。
    df1
    Out[338]:
          a    b     c
    0  55.0  0.0  20.0
    1  55.0  1.0  20.0
    2  55.0  2.0  20.0
    3  55.0  3.0  20.0
    4   NaN  NaN   NaN
    df2
    Out[339]:
          a      b
    1  11.0  111.0
    2  22.0  222.0
    3  33.0  333.0
    4   NaN  444.0
    5   NaN    NaN
    df1+df2
    Out[340]:
          a      b   c
    0   NaN    NaN NaN
    1  66.0  112.0 NaN
    2  77.0  224.0 NaN
    3  88.0  336.0 NaN
    4   NaN    NaN NaN
    5   NaN    NaN NaN
    df1.add(df2)
    Out[341]:
          a      b   c
    0   NaN    NaN NaN
    1  66.0  112.0 NaN
    2  77.0  224.0 NaN
    3  88.0  336.0 NaN
    4   NaN    NaN NaN
    5   NaN    NaN NaN
    

    在使用上述方法进行算术运算时,可以使用fill_value参数进行空值填充,会先填充后进行算术运算。

    df1.add(df2,fill_value=0)
    Out[343]:
          a      b     c
    0  55.0    0.0  20.0
    1  66.0  112.0  20.0
    2  77.0  224.0  20.0
    3  88.0  336.0  20.0
    4   NaN  444.0   NaN
    5   NaN    NaN   NaN
    

    (2)关联操作

    使用pd.merge方法对两个DataFrame对象进行关联操作,本质上与两张数据库的二维表的join操作效果相同。

    df6=pd.DataFrame({'a':{1:11,2:22,3:33},'b':{1:111,2:222,3:333},'c':{1:11,3:33,5:55}})
    df6
    Out[347]:
          a      b     c
    1  11.0  111.0  11.0
    2  22.0  222.0   NaN
    3  33.0  333.0  33.0
    5   NaN    NaN  55.0
    df7=pd.DataFrame({'b':{1:111,2:444,3:333},'c':{1:11,2:44,3:33}})
    df7
    Out[348]:
         b   c
    1  111  11
    2  444  44
    3  333  33
    pd.merge(df6,df7,on='b')
    Out[349]:
          a      b   c_x  c_y
    0  11.0  111.0  11.0   11
    1  33.0  333.0  33.0   33
    

    a. how参数决定关联方式,how='inner'相当于inner join,这是默认情况;how='left'相当于left join;how='right'相当于right join;how='outer'相当于cross join。

    pd.merge(df6,df7,on='b',how='left')
    Out[350]:
          a      b   c_x   c_y
    0  11.0  111.0  11.0  11.0
    1  22.0  222.0   NaN   NaN
    2  33.0  333.0  33.0  33.0
    3   NaN    NaN  55.0   NaN
    

    b. on参数决定关联条件。当两个DataFrame对象的关联列名相同时,使用on参数指定;当两个DataFrame对象的关联列名不同时,则使用left_on和right_on参数分别指定。

    pd.merge(df6,df7,left_on='a',right_on='c')
    Out[352]:
          a    b_x   c_x  b_y  c_y
    0  11.0  111.0  11.0  111   11
    1  33.0  333.0  33.0  333   33
    

    c. suffixes参数处理合并后相同列名的命名问题,确定合并后的后缀。

    pd.merge(df6,df7,on='b',suffixes=['_left','_right'])
    Out[351]:
          a      b  c_left  c_right
    0  11.0  111.0    11.0       11
    1  33.0  333.0    33.0       33
    

    d. right_index参数,取值为True代表右侧DataFrame的行索引作为连接键参与连接。
    e. left_index参数,取值为True代表左侧DataFrame的行索引作为连接键参与连接。

    pd.merge(df6,df7,left_on='a',right_index=True,how='left')
    Out[354]:
          a    b_x   c_x  b_y  c_y
    1  11.0  111.0  11.0  NaN  NaN
    2  22.0  222.0   NaN  NaN  NaN
    3  33.0  333.0  33.0  NaN  NaN
    5   NaN    NaN  55.0  NaN  NaN
    pd.merge(df6,df7,left_index=True,right_index=True)
    Out[355]:
          a    b_x   c_x  b_y  c_y
    1  11.0  111.0  11.0  111   11
    2  22.0  222.0   NaN  444   44
    3  33.0  333.0  33.0  333   33
    

    ##6、DataFrame对象与Series对象之间的操作 ###(1)算术运算 通过+、-、*、等运算符或者add、sub、mul、div等方法进行DataFrame对象和Series对象之间的算术运算。 默认将Series的索引匹配DataFrame的列索引,然后沿着行一直向下传播。
    df8=pd.DataFrame({'a':{1:100,2:200,3:300},'b':{1:200,2:300,3:400},'c':{1:300,2:400,3:500}})
    df8
    Out[360]:
         a    b    c
    1  100  200  300
    2  200  300  400
    3  300  400  500
    ser1=pd.Series([100,200,300],index=['a','b','c'])
    ser1
    Out[361]:
    a    100
    b    200
    c    300
    dtype: int64
    df8-ser1
    Out[362]:
         a    b    c
    1    0    0    0
    2  100  100  100
    3  200  200  200
    df8.sub(ser1)
    Out[363]:
         a    b    c
    1    0    0    0
    2  100  100  100
    3  200  200  200
    

    使用上述方法时,可以使用axis参数来设定二者索引的匹配方向,是按行索引匹配(axis=0),还是按列索引匹配(axis=1,默认)。索引没有对齐的元素,运算结果为NaN。

    df8.sub(ser1,axis=1)
    Out[364]:
         a    b    c
    1    0    0    0
    2  100  100  100
    3  200  200  200
    df8.sub(ser1,axis=0)
    Out[365]:
        a   b   c
    1 NaN NaN NaN
    2 NaN NaN NaN
    3 NaN NaN NaN
    a NaN NaN NaN
    b NaN NaN NaN
    c NaN NaN NaN
    ser2=df8['a']
    ser2
    Out[368]:
    1    100
    2    200
    3    300
    Name: a, dtype: int64
    df8.sub(ser2,axis=0)
    Out[369]:
       a    b    c
    1  0  100  200
    2  0  100  200
    3  0  100  200
    

    ##7.参考与感谢 [1] [利用Python进行数据分析](https://book.douban.com/subject/25779298/)


  • 相关阅读:
    Python高级数据处理与可视化(四)---- 数据存储
    Python高级数据处理与可视化(三)---- Matplotlib图像属性控制 & Pandas作图
    Notepad++
    HDU2819 Swap(二分匹配+输出结果)
    HDU1281 棋盘游戏(二分匹配+找必要的点)
    HDU1083 Courses(二分匹配)
    HDU2444 二分图判断+最大匹配
    HDU1045 Fire Net(二分匹配)
    exam1802 Bounty Hunter II(DAG的最小路径覆盖)
    SDUSTOJ 1801 LIS2(最长上升子序列不同值的数量)
  • 原文地址:https://www.cnblogs.com/hbsygfz/p/8880456.html
Copyright © 2020-2023  润新知