美文网首页数据结构开发程序员
数据分析之四:pandas库之索引对象和数学统计

数据分析之四:pandas库之索引对象和数学统计

作者: 无为无悔 | 来源:发表于2016-08-16 22:39 被阅读1964次

    1. pandas的索引对象


    任何数组都有一个Index对象,可以为DataFrame设置各种各样的Index,如DatetimeIndex可以用来表示时间戳,MultiIndex可以表示层次索引,这些Index的基类是Index,可以通过以下方式查看Index:

    In [227]: frame
    Out[227]: 
       0  1  2
    0  1  1  1
    1  2  2  2
    2  3  3  3
    
    # 此DataFrame的索引是RangeIndex类型
    In [228]: frame.index
    Out[228]: RangeIndex(start=0, stop=3, step=1)
    
    # 可以通过以下方式修改索引
    In [230]: frame.index = ['a','b','c']
    
    In [231]: frame
    Out[231]: 
       0  1  2
    a  1  1  1
    b  2  2  2
    c  3  3  3
    
    In [232]: frame.index
    Out[232]: Index([u'a', u'b', u'c'], dtype='object')
    
    # 但是不可以这样,因为Index对象不支持这种修改方式
    In [233]: idx = frame.index
    
    In [234]: idx[0] = 'A'
    

    1.1. 重新索引


    In [258]: arr = Series(randn(4), index=['b', 'c', 'a', 'd'])
    
    In [259]: arr
    Out[259]: 
    b    0.048503
    c   -2.836523
    a    0.231643
    d    1.272932
    dtype: float64
    
    
    # 重新索引后,索引值跟着索引改变了位置
    In [260]: arr1 = arr.reindex(['a', 'b', 'c', 'd', 'e'])
    
    In [261]: arr1
    Out[261]: 
    a    0.231643
    b    0.048503
    c   -2.836523
    d    1.272932
    e         NaN
    dtype: float64
    
    In [264]: frame = DataFrame(np.arange(9).reshape((3,3)), columns=['b', 'a', 'c'])
    
    In [265]: frame
    Out[265]: 
       b  a  c
    0  0  1  2
    1  3  4  5
    2  6  7  8
    
    # 同样,可以重排列索引,也可以同时对行和列重排
    In [266]: frame.reindex(columns=['a', 'b', 'c', 'd'])
    Out[266]: 
       a  b  c   d
    0  1  0  2 NaN
    1  4  3  5 NaN
    2  7  6  8 NaN
    
    

    1.2. 通过索引删除


    # 先来看缺省值的删除
    In [269]: frame
    Out[269]: 
       a  b  c   d
    0  1  0  2 NaN
    1  4  3  5 NaN
    2  7  6  8 NaN
    
    # 参数为1轴,表示删除1轴上带有缺省值NaN的一列
    # 若参数为0轴,删除所有值得到一个空的frame?
    In [270]: frame.dropna(axis=1)
    Out[270]: 
       a  b  c
    0  1  0  2
    1  4  3  5
    2  7  6  8
    
    # drop函数,默认参数是行索引,即index
    In [275]: frame.drop(0)
    Out[275]: 
       a  b  c   d
    1  4  3  5 NaN
    2  7  6  8 NaN
    
    # 若删除列,请指定轴方向
    n [277]: frame.drop('d', axis=1)
    Out[277]: 
       a  b  c
    0  1  0  2
    1  4  3  5
    2  7  6  8
    

    1.3. 通过索引过滤


    In [278]: frame
    Out[278]: 
       a  b  c   d
    0  1  0  2 NaN
    1  4  3  5 NaN
    2  7  6  8 NaN
    
    # 获取b列小于4的行
    In [280]: frame[frame['b'] < 4]
    Out[280]: 
       a  b  c   d
    0  1  0  2 NaN
    1  4  3  5 NaN
    
    # 获取b列小于4且c列小于3的行
    # 这里‘&’代表and,‘|’代表or
    In [281]: frame[(frame['b'] < 4) &  (frame['c'] < 3)]
    Out[281]: 
       a  b  c   d
    0  1  0  2 NaN
    
    

    1.4. 通过索引排序


    对行和列的索引进行排序使用sort_index函数,返回一个新的对象,若需要按值排序,Series使用order函数,DataFrame使用sort_values函数,排序的时候,缺省值默认是放到末尾的。

    In [294]: frame = DataFrame(np.arange(8).reshape(2,4), index=[3, 1], columns=['d', 'b', 'a', 'c'])
    
    In [295]: frame
    Out[295]: 
       d  b  a  c
    3  0  1  2  3
    1  4  5  6  7
    
    # 按照index升序排列
    In [296]: frame.sort_index()
    Out[296]: 
       d  b  a  c
    1  4  5  6  7
    3  0  1  2  3
    
    # 按照column生序排列
    In [297]: frame.sort_index(axis=1)
    Out[297]: 
       a  b  c  d
    3  2  1  3  0
    1  6  5  7  4
    
    # 同时按照行和列排序
    In [299]: frame.sort_index(axis=1).sort_index()
    Out[299]: 
       a  b  c  d
    1  6  5  7  4
    3  2  1  3  0
    
    # 按值排序,需指定轴方向和基准列
    In [311]: frame
    Out[311]: 
       d  b  a  c
    1  4  5  6  7
    3  0  1  2  3
    
    In [312]: frame.sort_values(by='c', axis=0)
    Out[312]: 
       d  b  a  c
    3  0  1  2  3
    1  4  5  6  7
    

    1.5 通过索引定位和切片


    • loc/iloc/ix方式

    loc、iloc以及ix都是定位DataFrame行以及进行索引切片的重要方法

    1. Positional-oriented (Python slicing style : exclusive of end)
    2. Label-oriented (Non-Python slicing style : inclusive of end)
    3. General (Either slicing style : depends on if the slice contains labels or positions)

    分别解释一下

    • iloc是基于位置的索引,参数只允许是RowID这样的整数,例如,选取第1-2行使用df.loc[1:3],注意第3行是不包含的(满足python style);

    • loc是基于标签的索引,也就是我们自定义的索引,同样选取第1-2行使用df.loc[1:2],注意它不满足python style;

    • ix是以上二者的综合,既可以使用RowID,又可以使用自定义索引,要视情况不同来使用,如果索引既有数字又有英文,那么这种方式是不建议使用的,很容易导致定位的混乱,可以想象,如果索引是A, B, C, D, 1, 2, 3,我们使用切片df.ix[:3]是否能得到我们想要的样子呢?

    所以,建议大家养成习惯,活用loc和iloc即可,附带loc切片选取数据块的方法:

    可以再研究下它们的效率,例如读取一个30k条记录的数据集,使用以下三种方式进行切片操作,效率相差不是很大,官方文档也未说明他们在效率上有何不同,以后可以使用更大的数据集来做实验,毕竟数据分析方面效率也是很重要的指标,选取的方法好了,工作效率也更高。

    In [42]: %timeit df.ix[:10]
    10000 loops, best of 3: 138 µs per loop
    
    In [43]: %timeit df.loc[:10]
    The slowest run took 4.89 times longer than the fastest. This could mean that an intermediate result is being cached.
    10000 loops, best of 3: 140 µs per loop
    
    In [44]: %timeit df.iloc[:11]
    10000 loops, best of 3: 130 µs per loop
    
    

    2. pandas统计


    一次性对所有列产生汇总统计可以用describe函数,包括数量count(非NA),平均值 mean,最小值min,最大值max,分位数quantile(25%/50%/75%),标准差std等,当然也可以调用相应的方法单独求出,默认不加参数都是对列操作。

    例如,对以下3×4的矩阵:

    In [314]: frame = DataFrame(randn(3, 4))
    
    In [315]: frame
    Out[315]: 
              0         1         2         3
    0  0.143605  0.543037  1.509424 -0.849529
    1  1.516573 -1.037837 -0.323093 -0.380521
    2 -0.488021 -1.007932 -0.751957  1.693078
    
    In [316]: frame.describe()
    Out[316]: 
                  0         1         2         3
    count  3.000000  3.000000  3.000000  3.000000
    mean   0.390719 -0.500911  0.144791  0.154343
    std    1.024889  0.904209  1.201103  1.353060
    min   -0.488021 -1.037837 -0.751957 -0.849529
    25%   -0.172208 -1.022885 -0.537525 -0.615025
    50%    0.143605 -1.007932 -0.323093 -0.380521
    75%    0.830089 -0.232447  0.593165  0.656278
    max    1.516573  0.543037  1.509424  1.693078
    
    In [317]: frame.max()
    Out[317]: 
    0    1.516573
    1    0.543037
    2    1.509424
    3    1.693078
    dtype: float64
    
    In [318]: frame.count()
    Out[318]: 
    0    3
    1    3
    2    3
    3    3
    dtype: int64
    
    In [319]: frame.sum()
    Out[319]: 
    0    1.172157
    1   -1.502732
    2    0.434374
    3    0.463028
    dtype: float64
    

    相关系数和协方差的计算也很方便,使用corrcov函数即可

    In [321]: frame = DataFrame({'col1':[1,3,4,3,4],'col2':[2,3,1,2,3],'col3':[1,5,2,4,4]})
    
    In [322]: frame
    Out[322]: 
       col1  col2  col3
    0     1     2     1
    1     3     3     5
    2     4     1     2
    3     3     2     4
    4     4     3     4
    
    # 列之间的相关系数
    # 默认参数method='pearson',此外还有kendall,spearman
    In [323]: frame.corr()
    Out[323]: 
              col1      col2      col3
    col1  1.000000  0.000000  0.496904
    col2  0.000000  1.000000  0.691023
    col3  0.496904  0.691023  1.000000
    
    # 列之间的协方差
    In [324]: frame.cov()
    Out[324]: 
          col1  col2  col3
    col1   1.5  0.00  1.00
    col2   0.0  0.70  0.95
    col3   1.0  0.95  2.70
    
    # 也可以单指定某一列计算
    In [331]: frame.corrwith(frame.col1)
    Out[331]: 
    col1    1.000000
    col2    0.000000
    col3    0.496904
    dtype: float64
    

    还有一个计算频率的方法value_counts,和apply函数结合使用,可以实现wordcount

    In [336]: wordcounts = frame.apply(pd.value_counts).fillna(0)
    
    # 左列是矩阵中的不同元素
    In [337]: wordcounts
    Out[337]: 
       col1  col2  col3
    1   1.0   1.0   1.0
    2   0.0   2.0   1.0
    3   2.0   2.0   0.0
    4   2.0   0.0   2.0
    5   0.0   0.0   1.0
    

    相关文章

      网友评论

      • DreamOver:请问一下博主,文中提到的 python style 是什么啊?

      本文标题:数据分析之四:pandas库之索引对象和数学统计

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