Python数据分析06:Pandas基本功能

CHAPTER 5

Getting Started with pandas


文章目录

  • CHAPTER 5
  • Getting Started with pandas
    • 5.2 基本功能(Essential Functionality)
      • 5.2.1 重新索引(Reindexing)
        • 5.2.1.1 reindex函数
        • 5.2.1.2 reindex函数各参数说明
        • 5.2.1.3 更改DataFrame行列索引
      • 5.2.2 丢弃指定轴上的项(Dropping Entries from an Axis)
        • 5.2.2.1 drop函数
      • 5.2.3 索引,选取,过滤(Indexing, Selection, and Filtering)
        • 5.2.3.1 Series的索引
        • 5.2.3.2 DataFrame的索引
        • 5.2.3.3 用loc和iloc进行选取
        • 5.2.3.4 DataFrame的索引选项
      • 5.2.4 整数索引(Integer Indexes)
      • 5.2.5 算术运算和数据对齐(Arithmetic and Data Alignment)
        • 5.2.5.1 带填充值的算数方法
        • 5.2.5.2 Series和DataFrame的算术方法
        • 5.2.5.3 DataFrame和Series之间的运算
      • 5.2.6 函数应用和映射(Function Application and Mapping)
        • 5.2.6.1 apply函数
      • 5.2.7 排序和排名(Sorting and Ranking)
        • 5.2.7.1 排序
        • 5.2.7.2 排名
        • 5.2.7.3 排名时用于破坏平级关系的方法
      • 5.2.8 带有重复标签的轴索引(Axis Indexes with Duplicate Labels)


5.2 基本功能(Essential Functionality)

下面我们来从SeriesDataFrame中的数据入手,看看pandas最重要也最基础的内容。

5.2.1 重新索引(Reindexing)

pandas中一个重要的方法是reindex,用来在创建object的时候遵照一个新的index。如下例:

>>>import pandas as pd
>>>obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c'])
>>>obj
d    4.5
b    7.2
a   -5.3
c    3.6
dtype: float64

5.2.1.1 reindex函数

在series上调用reindex能更改index,如果没有对应index的话会引入缺失数据:

>>>obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])
>>>obj2
a   -5.3
b    7.2
c    3.6
d    4.5
e    NaN
dtype: float64

在处理时间序列这样的数据时,我们可能需要在reindexing的时候需要修改值。method选项能做到这一点,比如设定methodffill:

>>>obj3 = pd.Series(['blue', 'purple', 'yellow'], index=[0, 2, 4])
>>>obj3
0      bule
2    purple
4    yellow
dtype: object
>>>obj3.reindex(range(6), method='ffill')
0      bule
1      bule
2    purple
3    purple
4    yellow
5    yellow
dtype: object

5.2.1.2 reindex函数各参数说明

参数 说明
index 用作索引的新序列,既可以是Index实例,也可是其他序列型的Python数据对象
method 插值(填充)方式,具体见下表
fill_value 在需要重新索引的过程中,引入缺失值时使用的代替值
limit 向前或向后填充时的最大填充量
tolerance 向前向后填充时,填充不准确匹配项的最大间距(绝对值距离)
level 在MultiIndex的指定级别上匹配简单索引
copy 默认为True,无论如何都复制;如果为False,则新旧相同就不复制

5.2.1.3 更改DataFrame行列索引

对于DataFramereindex能更改row index,或column index。

更改行:

>>>import numpy as np
>>>frame = pd.DataFrame(np.arange(9).reshape((3, 3)),
>>>                     index=['a', 'c', 'd'],
>>>                     columns=['Ohio', 'Texas', 'California'])
>>>frame
   Ohio  Texas  California
a     0      1           2
c     3      4           5
d     6      7           8
>>>frame2 = frame.reindex(['a', 'b', 'c', 'd'])
>>>frame2
   Ohio  Texas  California
a   0.0    1.0         2.0
b   NaN    NaN         NaN
c   3.0    4.0         5.0
d   6.0    7.0         8.0

更改列:

>>>states = ['Texas', 'Utah', 'California']
>>>frame.reindex(columns=states)
   Texas  Utah  California
a      1   NaN           2
c      4   NaN           5
d      7   NaN           8

还可以使用loc——更简洁的reindex

>>>frame.loc[['a', 'b', 'c', 'd'], states]
   Texas  Utah  California
a    1.0   NaN         2.0
b    NaN   NaN         NaN
c    4.0   NaN         5.0
d    7.0   NaN         8.0

5.2.2 丢弃指定轴上的项(Dropping Entries from an Axis)

5.2.2.1 drop函数

  • 对于series,drop会返回一个新的object,并删去你指定的axis的值:
>>>obj = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
>>>obj
a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64
>>>new_obj = obj.drop('c')
>>>new_obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64
>>>obj.drop(['d', 'c'])
a    0.0
b    1.0
e    4.0
dtype: float64
  • 对于DataFrame,可以drop任意轴上的索引值:
>>>data = pd.DataFrame(np.arange(16).reshape((4, 4)),
>>>                    index=['Ohio', 'Colorado', 'Utah', 'New York'],
>>>                    columns=['one', 'two', 'three', 'four'])
>>>data
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

行处理:如果用a sequence of labels(一个标签序列)来调用drop,会删去row labels删除值:

>>>data.drop(['Colorado', 'Ohio'])
          one  two  three  four
Utah        8    9     10    11
New York   12   13     14    15

列处理:drop列的话,设定axis=1或axis=‘columns’:

>>>data.drop('two', axis=1)
          one  three  four
Ohio        0      2     3
Colorado    4      6     7
Utah        8     10    11
New York   12     14    15
>>>data.drop(['two', 'four'], axis='columns')
          one  three
Ohio        0      2
Colorado    4      6
Utah        8     10
New York   12     14

drop也可以不返回一个新的object,而是直接更改series或dataframe:

>>>obj.drop('c', inplace=True)
>>>obj
a    0.0
b    1.0
d    3.0
e    4.0
dtype: float64

5.2.3 索引,选取,过滤(Indexing, Selection, and Filtering)

5.2.3.1 Series的索引

series indexing(obj[…]) 相当于numpy的array indexing, 而且除了整数,还可以使用series的index:

>>>obj = pd.Series(np.arange(4.), index=['a', 'b', 'c', 'd'])
>>>obj
a    0.0
b    1.0
c    2.0
d    3.0
dtype: float64
>>>obj['b']
1.0
>>>obj[1]
1.0
>>>obj[2:4]
c    2.0
d    3.0
dtype: float64
>>>obj[['b', 'a', 'd']]
b    1.0
a    0.0
d    3.0
dtype: float64
>>>obj[[1, 3]]
b    1.0
d    3.0
dtype: float64
>>>obj[obj < 2]
a    0.0
b    1.0
dtype: float64

用label来slicing(切片)的时候,和python的切片不一样的在于会包括尾节点:

>>>obj['b':'c']
b    1.0
c    2.0
dtype: float64

直接给选中的label更改值:

>>>obj['b':'c'] = 5
>>>obj
a    0.0
b    5.0
c    5.0
d    3.0
dtype: float64

5.2.3.2 DataFrame的索引

  • 通过一个值或序列,对DataFrame索引:
>>>data = pd.DataFrame(np.arange(16).reshape((4, 4)),
>>>                    index=['Ohio', 'Colorado', 'Utah', 'New York'],
>>>                    columns=['one', 'two', 'three', 'four'])
>>>data
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15
>>>data['two']
Ohio         1
Colorado     5
Utah         9
New York    13
Name: two, dtype: int32
>>>data[['three', 'one']]
          three  one
Ohio          2    0
Colorado      6    4
Utah         10    8
New York     14   12
  • 通过布尔数组对DataFrame进行索引:
>>>data[:2]
          one  two  three  four
Ohio        0    1      2     3
Colorado    4    5      6     7
>>>data[data['three'] > 5]
          one  two  three  four
Colorado    4    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

行选择的语法格式data[:2]是很方便的。给[]里传入一个list的话,可以选择列。

  • 通过布尔型DataFrame(由标量比较运算得出)进行索引:
>>>data < 5
            one    two  three   four
Ohio       True   True   True   True
Colorado   True  False  False  False
Utah      False  False  False  False
New York  False  False  False  False
>>>data[data < 5] = 0
>>>data
          one  two  three  four
Ohio        0    0      0     0
Colorado    0    5      6     7
Utah        8    9     10    11
New York   12   13     14    15

5.2.3.3 用loc和iloc进行选取

对于DataFrame的行标签索引,lociloc比较特殊。这两个方法能通过axis labels(loc)或integer(iloc)来选择行或列。

栗子,选中一行多列by label:

>>>data.loc['Colorado', ['two', 'three']]
two      5
three    6
Name: Colorado, dtype: int32

iloc实现相同的效果:

>>>data.iloc[2, [3, 0, 1]]
four    11
one      8
two      9
Name: Utah, dtype: int32
>>>data.iloc[2]
one       8
two       9
three    10
four     11
Name: Utah, dtype: int32
>>>data.iloc[[1, 2], [3, 0, 1]]
          four  one  two
Colorado     7    0    5
Utah        11    8    9

这两个索引函数也适用于⼀个标签或多个标签的切片:

>>>data.loc[:'Utah', 'two']
Ohio        0
Colorado    5
Utah        9
Name: two, dtype: int32
>>>data.iloc[:, :3][data.three > 5]
          one  two  three
Colorado    0    5      6
Utah        8    9     10
New York   12   13     14

5.2.3.4 DataFrame的索引选项

类型 说明
df[val] 从DataFrame选取单列或列子集;布尔型数组(过滤行)、切片(切片行)
或布尔型DataFrame(根据条件设置值)
df.loc[val] 通过标签,选取DataFrame的单个行或行子集
df.loc[:, val] 通过标签,选组单列或列子集
df.loc[val1, val2] 通过标签,同时选取行和列
df.iloc[where] 通过整数位置,从DataFrame选取单个行或行子集
df.iloc[:, where] 通过整数位置,从DataFrame选取单个列或列子集
df.iloc[where_i, where_j] 通过整数位置,同时选取行和列
df.at[label_i, label_j] 通过行和列标签,选取单一的标量
df.iat[i, j] 通过行和列实务位置(整数),选取单一的标量
reindex method 通过标签选取行和列
get_value, set_value methods 通过行和列标签选取单一值

5.2.4 整数索引(Integer Indexes)

一些新手再用integer来index的时候,总是会出错。因为这种方法和python用于list和tuple的indexing方法不同。

比如,你不希望下面的代码出现error:

>>>ser = pd.Series(np.arange(3.))
>>>ser
0    0.0
1    1.0
2    2.0
dtype: float64
>>>ser[-1]
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-58-44969a759c20> in <module>
----> 1 ser[-1]
"...省略..."
KeyError: -1

pandas在整数索引上可能会出错,另一方面,如果用非整数来做index,就没有歧义了:

>>>ser2 = pd.Series(np.arange(3.), index=['a', 'b', 'c'])
>>>ser2[-1]
2.0

为了保持连贯性,如果axis index里包含integer,那么选择数据的时候,就会使用标签。为了更精确地选择,使用loc(for label)或ilco(for integers):

>>>ser[:1]
0    0.0
dtype: float64
>>>ser.loc[:1]
0    0.0
1    1.0
dtype: float64
>>>ser.iloc[:1]
0    0.0
dtype: float64

5.2.5 算术运算和数据对齐(Arithmetic and Data Alignment)

pandas最重要的⼀个功能是,它可以对不同索引的对象进⾏算术运算。在将对象相加时,如果存在不同的索引,则结果的索引就是该索引对的并集。

>>>s1 = pd.Series([7.3, -2.5, 3.4, 1.5], index=['a', 'c', 'd', 'e'])
>>>s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],
>>>               index=['a', 'c', 'e', 'f', 'g'])
>>>s1
a    7.3
c   -2.5
d    3.4
e    1.5
dtype: float64
>>>s2
a    2.1
c    3.6
e   -1.5
f    4.0
g    3.1
dtype: float64
>>>s1 + s2
a    9.4
c    1.1
d    NaN
e    0.0
f    NaN
g    NaN
dtype: float64

这种数据对齐的方式(internal data alignment)引入了很多缺失值,这些缺失值会被用在之后的算数计算中。

在DataFrame中,数据对齐同时发生在行和列上:

>>>df1 = pd.DataFrame(np.arange(9.).reshape((3, 3)), columns=list('bcd'),
>>>                   index=['Ohio', 'Texas', 'Colorado'])
>>>df2 = pd.DataFrame(np.arange(12.).reshape((4, 3)), columns=list('bde'),
>>>                   index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>>df1
            b    c    d
Ohio      0.0  1.0  2.0
Texas     3.0  4.0  5.0
Colorado  6.0  7.0  8.0
>>>df2
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0

相加的结果就是两个DataFrame,行和列的合集:

>>>df1 + df2
            b   c     d   e
Colorado  NaN NaN   NaN NaN
Ohio      3.0 NaN   6.0 NaN
Oregon    NaN NaN   NaN NaN
Texas     9.0 NaN  12.0 NaN
Utah      NaN NaN   NaN NaN

因为’c’和’e’列都不同时在两个DataFrame里,所有全是缺失值。对于行,即使有相同的,但列不一样的话也会是缺失值。

如果两个DataFrame相加,而且没有column和row,结果会全是null:

>>>df1 = pd.DataFrame({
     'A': [1, 2]})
>>>df2 = pd.DataFrame({
     'B': [3, 4]})
>>>df1
   A
0  1
1  2
>>>df2
   B
0  3
1  4
>>>df1 - df2
    A   B
0 NaN NaN
1 NaN NaN

5.2.5.1 带填充值的算数方法

对于上面那些缺失值,我们想要填上0:

>>>df1 = pd.DataFrame(np.arange(12.).reshape((3, 4)),
>>>                   columns=list('abcd'))
>>>df2 = pd.DataFrame(np.arange(20.).reshape((4, 5)),
>>>                   columns=list('abcde'))
>>>df2.loc[1, 'b'] = np.nan
>>>df1
     a    b     c     d
0  0.0  1.0   2.0   3.0
1  4.0  5.0   6.0   7.0
2  8.0  9.0  10.0  11.0
>>>df2
      a     b     c     d     e
0   0.0   1.0   2.0   3.0   4.0
1   5.0   NaN   7.0   8.0   9.0
2  10.0  11.0  12.0  13.0  14.0
3  15.0  16.0  17.0  18.0  19.0

不填充的结果:

>>>df1 + df2
      a     b     c     d   e
0   0.0   2.0   4.0   6.0 NaN
1   9.0   NaN  13.0  15.0 NaN
2  18.0  20.0  22.0  24.0 NaN
3   NaN   NaN   NaN   NaN NaN

使用参数fill_value进行填充:

>>>df1.add(df2, fill_value=0)
      a     b     c     d     e
0   0.0   2.0   4.0   6.0   4.0
1   9.0   5.0  13.0  15.0   9.0
2  18.0  20.0  22.0  24.0  14.0
3  15.0  16.0  17.0  18.0  19.0

算术方法:除法运算

>>>1 / df1
       a         b         c         d
0    inf  1.000000  0.500000  0.333333
1  0.250  0.200000  0.166667  0.142857
2  0.125  0.111111  0.100000  0.090909
>>>df1.rdiv(1)
       a         b         c         d
0    inf  1.000000  0.500000  0.333333
1  0.250  0.200000  0.166667  0.142857
2  0.125  0.111111  0.100000  0.090909

reindex(重建索引)的时候,也可以使用fill_value:

>>>df1.reindex(columns=df2.columns, fill_value=0)
     a    b     c     d  e
0  0.0  1.0   2.0   3.0  0
1  4.0  5.0   6.0   7.0  0
2  8.0  9.0  10.0  11.0  0

5.2.5.2 Series和DataFrame的算术方法

方法 说明
add, radd 用于加法(+)的方法
sub, rsub 用于减法(-)的方法
div, rdiv 用于除法(/)的方法
floordiv, rfloordiv 用于底除(//)的方法
mul, rmul 用于乘法(*)的方法
pow, rpow 用于指数(**)的方法

5.2.5.3 DataFrame和Series之间的运算

先来看⼀个栗子,计算⼀个⼆维数组与其某行之间的差:

>>>arr = np.arange(12.).reshape((3, 4))
>>>arr
array([[ 0.,  1.,  2.,  3.],
       [ 4.,  5.,  6.,  7.],
       [ 8.,  9., 10., 11.]])
>>>arr[0]
array([0., 1., 2., 3.])
>>>arr - arr[0]
array([[0., 0., 0., 0.],
       [4., 4., 4., 4.],
       [8., 8., 8., 8.]])

可以看到,这个减法是用在了每一行上。这种操作叫broadcasting,在Appendix A有更详细的解释。DataFrame和Series的操作也类似:

>>>frame = pd.DataFrame(np.arange(12.).reshape((4, 3)),
>>>                     columns=list('bde'),
>>>                     index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>>series = frame.iloc[0]
>>>frame
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0
>>>series
b    0.0
d    1.0
e    2.0
Name: Utah, dtype: float64

可以理解为series的index与dataframe的列匹配,broadcasting down the rows(向下按行广播):

>>>frame - series
          b    d    e
Utah    0.0  0.0  0.0
Ohio    3.0  3.0  3.0
Texas   6.0  6.0  6.0
Oregon  9.0  9.0  9.0

如果一个index既不在DataFrame的column中,也不再Series里的index中,那么结果也是合集:

>>>series2 = pd.Series(range(3), index=['b', 'e', 'f'])
>>>frame + series2
          b   d     e   f
Utah    0.0 NaN   3.0 NaN
Ohio    3.0 NaN   6.0 NaN
Texas   6.0 NaN   9.0 NaN
Oregon  9.0 NaN  12.0 NaN

如果想要在列上广播,去匹配行,必须要用到算数方法:

>>>series3 = frame['d']
>>>frame
          b     d     e
Utah    0.0   1.0   2.0
Ohio    3.0   4.0   5.0
Texas   6.0   7.0   8.0
Oregon  9.0  10.0  11.0
>>>series3
Utah       1.0
Ohio       4.0
Texas      7.0
Oregon    10.0
Name: d, dtype: float64
>>>frame.sub(series3, axis='index')  #减法算术运算,见上表
Out[53]: 
          b    d    e
Utah   -1.0  0.0  1.0
Ohio   -1.0  0.0  1.0
Texas  -1.0  0.0  1.0
Oregon -1.0  0.0  1.0

axis参数就是用来匹配轴的。在这个例子里是匹配dataframe的row index(axis='index or axis=0),然后再广播。

5.2.6 函数应用和映射(Function Application and Mapping)

numpy的ufuncs(element-wise数组方法)也能用在pandas的object上:

>>>frame = pd.DataFrame(np.random.randn(4, 3), columns=list('bde'),
>>>                     index=['Utah', 'Ohio', 'Texas', 'Oregon'])
>>>frame
               b         d         e
Utah    0.392567  0.271998  0.790944
Ohio    0.788808  1.909102  0.039790
Texas   0.511341  1.029418  0.081864
Oregon  1.189705  0.692081  0.834665
>>>np.abs(frame)
               b         d         e
Utah    1.282098  1.229175  0.732095
Ohio    0.950254  1.295434  1.679189
Texas   0.874102  1.274932  0.844413
Oregon  0.914953  2.101899  0.613982

5.2.6.1 apply函数

另⼀个常见的操作是,将函数应用到由各列或行所形成的⼀维数组上。DataFrame的apply函数即可实现此功能:

>>>f = lambda x: x.max() - x.min()
>>>frame.apply(f)
b    2.232352
d    3.397333
e    2.523603
dtype: float64

这里函数f,是计算series中最大值和最小值的差,frame中有几列,这个函数就被调用几次。作为结果的series,它的index就是frame的column。

如果你传入axis='column'用于apply,那么函数会被用在每一行:

>>>frame.apply(f, axis='columns')
Utah      2.725222
Ohio      1.672987
Texas     1.896290
Oregon    1.308482
dtype: float64

像是sum, mean这样的数组统计方法,DataFrame中已经集成了,所以没必要用apply

apply不会返回标量,只会返回一个含有多个值的series:

>>>def f(x):
>>>    return pd.Series([x.min(), x.max()], index=['min', 'max'])
>>>frame.apply(f)
            b         d         e
min -0.950254 -1.295434 -1.679189
max  1.282098  2.101899  0.844413

element-wise的python函数也能用。假设想要格式化frame中的浮点数,变为string。可以用applymap

>>>format = lambda x: '%.2f' % x
>>>frame.applymap(format)
            b      d      e
Utah     1.28   1.23  -0.73
Ohio    -0.95  -1.30  -1.68
Texas   -0.87   1.27   0.84
Oregon  -0.91   2.10   0.61

applymap的做法是,series有一个map函数,能用来实现element-wise函数:

>>>frame['e'].map(format)
Utah       1.63
Ohio       1.28
Texas     -1.20
Oregon     0.09
Name: e, dtype: object

5.2.7 排序和排名(Sorting and Ranking)

5.2.7.1 排序

  • sort_index函数

按row或column的索引来排序的话,可以用sort_index函数,会返回一个新的object:

>>>obj = pd.Series(range(4), index=['d', 'a', 'b', 'c'])
>>>obj.sort_index()
a    1
b    2
c    3
d    0
dtype: int64

在DataFrame,可以用index或其他axis来排序:

>>>frame = pd.DataFrame(np.arange(8).reshape((2, 4)),
>>>                     index=['three', 'one'],
>>>                     columns=['d', 'a', 'b', 'c'])
>>>frame
       d  a  b  c
three  0  1  2  3
one    4  5  6  7
>>>frame.sort_index()
       d  a  b  c
one    4  5  6  7
three  0  1  2  3
>>>frame.sort_index(axis=1)
       a  b  c  d
three  1  2  3  0
one    5  6  7  4

默认是升序,可以设置降序:

>>>frame.sort_index(axis=1, ascending=False)
       d  c  b  a
three  0  3  2  1
one    4  7  6  5
  • sort_values函数

通过值来排序,用sort_values函数:

>>>obj = pd.Series([4, 7, -3, 2])
>>>obj.sort_values()
2   -3
3    2
0    4
1    7
dtype: int64

若存在缺失值,则缺失值会被排在最后:

>>>obj = pd.Series([4, np.nan, 7, np.nan, -3, 2])
>>>obj.sort_values()
4   -3.0
5    2.0
0    4.0
2    7.0
1    NaN
3    NaN
dtype: float64

对于一个DataFrame,可以用一列或多列作为排序keys。这样的话,只需要把一列或多列的名字导入到sort_values即可:

>>>frame = pd.DataFrame({
     'b': [4, 7, -3, 2], 'a': [0, 1, 0, 1]})
>>>frame
   b  a
0  4  0
1  7  1
2 -3  0
3  2  1
>>>frame.sort_values(by='b')
   b  a
2 -3  0
3  2  1
0  4  0
1  7  1

多列排序需要传入一个list:

>>>frame.sort_values(by=['a', 'b'])
   b  a
2 -3  0
0  4  0
3  2  1
1  7  1

5.2.7.2 排名

  • rank函数

平均排名(存在相同值时出现)

ranking(排名)是给有效的数据分配数字。rank函数能用于series和DataFrame,rank函数默认会给每个group一个mean rank(平均排名)。rank表示在这个数在原来的Series中排第几名,有相同的数,取其排名平均(默认)作为值:

>>>obj = pd.Series([7, -5, 7, 4, 2, 0, 4])
>>>obj
0    7
1   -5
2    7
3    4
4    2
5    0
6    4
dtype: int64
>>>obj.sort_values()  #给值排序
1   -5
5    0
4    2
3    4
6    4
0    7
2    7
dtype: int64
>>>obj.rank()
0    6.5
1    1.0
2    6.5
3    4.5
4    3.0
5    2.0
6    4.5
dtype: float64

解释一下先,在obj中,4和4的排名是第4名和第五名,取平均得4.5。7和7的排名分别是第六名和第七名,则其排名取平均得6.5。

顺序排名(我自己起的名字哈)

也可以根据值在原数据中出现的顺序给出排名:

>>>obj.rank(method='first')
0    6.0
1    1.0
2    7.0
3    4.0
4    3.0
5    2.0
6    5.0
dtype: float64

这里没有给0和2(指两个数字7)赋予average rank 6.5,而是给第一个看到的7(label 0)设置rank为6,第二个看到的7(label 2)设置rank为7。

也可以设置降序:

>>># Assign tie values the maximum rank in the group
>>>obj.rank(ascending=False, method='max')
0    2.0
1    7.0
2    2.0
3    4.0
4    5.0
5    6.0
6    4.0
dtype: float64

DataFrame可以根据行或列来计算rank:

>>>frame = pd.DataFrame({
     'b': [4.3, 7, -3, 2], 'a': [0, 1, 0, 1],
>>>                      'c': [-2, 5, 8, -2.5]})
>>>frame
     b  a    c
0  4.3  0 -2.0
1  7.0  1  5.0
2 -3.0  0  8.0
3  2.0  1 -2.5
>>>frame.rank(axis='columns')  #"columns"表示列与列之间的排序(即每一行里数据间的排序)
     b    a    c
0  3.0  2.0  1.0
1  3.0  1.0  2.0
2  1.0  2.0  3.0
3  3.0  2.0  1.0

5.2.7.3 排名时用于破坏平级关系的方法

method 描述
‘average’ 默认值,将平均排名分配给组中的每个对象
‘min’ 是用整个分组的最小排名
‘max’ 是用整个分组的最大排名
‘first’ 按值在原始数据中出现的顺序分配排名
‘dense’ 类似于’min’方法,但是排名总是在组间增加1,而不是组中相同的元素数

5.2.8 带有重复标签的轴索引(Axis Indexes with Duplicate Labels)

我们看到的所有例子都有唯一的轴标签(索引值)。一些pandas函数(reindex),需要label是唯一的,但这并不是强制性的。比如下面有一个重复的索引:

>>>obj = pd.Series(range(5), index=['a', 'a', 'b', 'b', 'c'])
>>>obj
a    0
a    1
b    2
b    3
c    4
dtype: int64

index的is_unique特性能告诉我们label是否是唯一的:

>>>obj.index.is_unique
False

数据选择对于重复label则表现有点不同。如果一个label有多个值,那么就会返回一个series, 如果是label只对应一个值的话,会返回一个标量:

>>>obj['a']
a    0
a    1
dtype: int64
>>>obj['c']
4

这个选择的逻辑也适用于DataFrame:

>>>df = pd.DataFrame(np.random.randn(4, 3), index=['a', 'a', 'b', 'b'])
>>>df
          0         1         2
a  0.862580 -0.010032  0.050009
a  0.670216  0.852965 -0.955869
b -0.023493 -2.304234 -0.652469
b -1.218302 -1.332610  1.074623
>>>df.loc['b']
          0         1         2
b -0.023493 -2.304234 -0.652469
b -1.218302 -1.332610  1.074623

参考资料:

  • 利用Python进行数据分析学习笔记(有惊喜^_^
  • 书籍:《Python for Data Analysis》

你可能感兴趣的:(利用Python进行数据分析,python,数据分析)