深入浅出Pandas:利用Python进行数据处理与分析
上QQ阅读APP看书,第一时间看更新

5.3 数据排序

数据排序是指按一定的顺序将数据重新排列,帮助使用者发现数据的变化趋势,同时提供一定的业务线索,还具有对数据纠错、分类等作用。本节将介绍一些Pandas用来进行数据排序的方法。

5.3.1 索引排序

df.sort_index()实现按索引排序,默认以从小到大的升序方式排列。如希望按降序排序,传入ascending=False:

# 索引降序
df.sort_index(ascending=False)
'''
        name team  Q1  Q2  Q3  Q4
99       Ben    E  21  43  41  74
98       Eli    E  11  74  58  91
97  Lincoln4    C  98  93   1  20
96   Austin7    C  21  31  30  43
95   Gabriel    C  48  59  87  74
..       ...  ...  ..  ..  ..  ..
4        Oah    D  65  49  61  86
3      Eorge    C  93  96  71  78
2        Ack    A  57  60  18  84
1       Arry    C  36  37  37  57
0      Liver    E  89  21  24  64

[100 rows x 6 columns]
'''

按列索引名排序:

# 在列索引方向上排序
df.sort_index(axis=1, ascending=False)
'''
   team      name  Q4  Q3  Q2  Q1
0     E     Liver  64  24  21  89
1     C      Arry  57  37  37  36
2     A       Ack  84  18  60  57
3     C     Eorge  78  71  96  93
4     D       Oah  86  61  49  65
..  ...       ...  ..  ..  ..  ..
95    C   Gabriel  74  87  59  48
96    C   Austin7  43  30  31  21
97    C  Lincoln4  20   1  93  98
98    E       Eli  91  58  74  11
99    E       Ben  74  41  43  21

[100 rows x 6 columns]
'''

更多方法如下:

s.sort_index() # 升序排列
df.sort_index() # df也是按索引进行排序
df.team.sort_index()
s.sort_index(ascending=False) # 降序排列
s.sort_index(inplace=True) # 排序后生效,改变原数据
# 索引重新0-(n-1)排,很有用,可以得到它的排序号
s.sort_index(ignore_index=True)
s.sort_index(na_position='first') # 空值在前,另'last'表示空值在后
s.sort_index(level=1) # 如果多层,排一级
s.sort_index(level=1, sort_remaining=False) # 这层不排
# 行索引排序,表头排序
df.sort_index(axis=1) # 会把列按列名顺序排列

df.reindex()指定自己定义顺序的索引,实现行和列的顺序重新定义:

df = pd.DataFrame({
    'A': [1,2,4],
    'B': [3,5,6]
}, index=['a', 'b', 'c'])
df
'''
   A  B
a  1  3
b  2  5
c  4  6
'''

# 按要求重新指定索引顺序
df.reindex(['c', 'b', 'a'])
'''
   A  B
c  4  6
b  2  5
a  1  3
'''

# 指定列顺序
df.reindex(['B', 'A'], axis=1)
'''
   B  A
a  3  1
b  5  2
c  6  4
'''

5.3.2 数值排序

数据值的排序主要使用sort_values(),数字按大小顺序,字符按字母顺序。Series和DataFrame都支持此方法:

df.Q1.sort_values()
'''
37     1
39     2
85     2
58     4
82     4
      ..
3     93
88    96
38    97
19    97
97    98
Name: Q1, Length: 100, dtype: int64
'''

DataFrame需要传入一个或多个排序的列名:

df.sort_values('Q4')
'''
       name team  Q1  Q2  Q3  Q4
56    David    B  21  47  99   2
19      Max    E  97  75  41   3
90     Leon    E  38  60  31   7
6      Acob    B  61  95  94   8
88    Aaron    A  96  75  55   8
..      ...  ...  ..  ..  ..  ..
75  Stanley    A  69  71  39  97
36    Jaxon    E  88  98  19  98
62  Matthew    C  44  33  41  98
72    Luke6    D  15  97  95  99
60   Ronnie    B  53  13  34  99

[100 rows x 6 columns]
'''

默认排序是升序,但可以指定排序方式,下例先按team升序排列,如遇到相同的team再按name降序排列。

df.sort_values(by=['team', 'name'], ascending=[True, False])
'''
       name team  Q1  Q2  Q3  Q4
79    Tyler    A  75  16  44  63
40     Toby    A  52  27  17  68
75  Stanley    A  69  71  39  97
34  Reggie1    A  30  12  23   9
9     Oscar    A  77   9  26  67
..      ...  ...  ..  ..  ..  ..
82     Finn    E   4   1  55  32
98      Eli    E  11  74  58  91
76   Dexter    E  73  94  53  20
99      Ben    E  21  43  41  74
41    Arlo8    E  48  34  52  51

[100 rows x 6 columns]
'''

其他常用方法如下:

s.sort_values(ascending=False) # 降序
s.sort_values(inplace=True) # 修改生效
s.sort_values(na_position='first') # 空值在前
# df按指定字段排列
df.sort_values(by=['team'])
df.sort_values('Q1')
# 按多个字段,先排team,在同team内再看Q1
df.sort_values(by=['team', 'Q1'])
# 全降序
df.sort_values(by=['team', 'Q1'], ascending=False)
# 对应指定team升Q1降
df.sort_values(by=['team', 'Q1'], ascending=[True, False])
# 索引重新0-(n-1)排
df.sort_values('team', ignore_index=True)

5.3.3 混合排序

有时候需要用索引和数据值混合排序。下例中假如name是索引,我们需要先按team排名,再按索引排名:

df.set_index('name', inplace=True) # 设置name为索引
df.index.names = ['s_name'] # 给索引起名
df.sort_values(by=['s_name', 'team']) # 排序
'''
        team  Q1  Q2  Q3  Q4
name
Aaron      A  96  75  55   8
Ack        A  57  60  18  84
Acob       B  61  95  94   8
Adam       C  90  32  47  39
Aiden      D  20  31  62  68
...      ...  ..  ..  ..  ..
Toby       A  52  27  17  68
Tommy      C  29  44  28  76
Tyler      A  75  16  44  63
William    C  80  68   3  26
Zachary    E  12  71  85  93

[100 rows x 5 columns]
'''

以下方法也可以实现上述需求,不过要注意顺序:

# 设置索引,按team排序,再按索引排序
df.set_index('name').sort_values('team').sort_index()

另外,还可以使用df.reindex(),通过给定新的索引方式来排名,按照这个思路可以实现人工指定任意顺序。

# 按姓名排序后取出排名后的索引列表
df.name.sort_values().index
'''
Int64Index([88,  2,  6, 33, 94, 83, 57, 63, 32, 12, 41,  1, 22, 96, 99, 44, 71,
            52, 67, 86, 49, 91, 28, 56, 76, 42, 30, 98, 38, 73, 78, 81,  3, 21,
            89, 27, 82, 53, 95, 92, 39,  5, 25, 64, 17, 51, 68, 24, 61, 47, 15,
            93, 36, 66, 50, 31, 16, 43, 84, 10, 90, 58,  7, 85, 97,  0, 11, 48,
            87, 59, 20, 72, 23, 62, 19, 77, 70,  4, 54,  9,  8, 34, 65, 29, 74,
            60, 45, 80, 35, 37, 75, 26, 13, 69, 14, 40, 46, 79, 18, 55],
           dtype='int64')
'''
# 将新的索引应用到数据中
df.reindex(df.name.sort_values().index)
'''
       name team  Q1  Q2  Q3  Q4
88    Aaron    A  96  75  55   8
2       Ack    A  57  60  18  84
6      Acob    B  61  95  94   8
33     Adam    C  90  32  47  39
94    Aiden    D  20  31  62  68
..      ...  ...  ..  ..  ..  ..
40     Toby    A  52  27  17  68
46    Tommy    C  29  44  28  76
79    Tyler    A  75  16  44  63
18  William    C  80  68   3  26
55  Zachary    E  12  71  85  93

[100 rows x 6 columns]
'''

5.3.4 按值大小排序

nsmallest()和nlargest()用来实现数字列的排序,并可指定返回的个数:

# 先按Q1最小在前,如果相同,Q2小的在前
df.nsmallest(5, ['Q1', 'Q2'])
'''
         name team  Q1  Q2  Q3  Q4
37  Sebastian    C   1  14  68  48
85       Liam    B   2  80  24  25
39     Harley    B   2  99  12  13
82       Finn    E   4   1  55  32
58      Lewis    B   4  34  77  28
'''

以上显示了前5个最小的值,仅支持数字类型的排序。下面是几个其他示例:

s.nsmallest(3) # 最小的3个
s.nlargest(3) # 最大的3个
# 指定列
df.nlargest(3, 'Q1')
df.nlargest(5, ['Q1', 'Q2'])
df.nsmallest(5, ['Q1', 'Q2'])

5.3.5 小结

本节介绍了索引的排序、数值的排序以及索引和数值混合的排序方法。在实际需求中,更加复杂的排序可能需要通过计算增加辅助列来实现。