行排序

“NBA 是世界上薪资最高的职业体育联盟,” CNN 于 2016 年 3 月报道。表格 nba_salaries 包含了 2015-2016 赛季所有美国国家篮球协会球员的薪资。

每一行代表一名球员。列如下:

列标签 描述
PLAYER 球员姓名
POSITION 球员在球队中的位置
TEAM 球队名称
'15-'16 SALARY 球员 2015-2016 赛季薪资(百万美元)

位置的代码为 PG(控球后卫)、SG(得分后卫)、PF(大前锋)、SF(小前锋)和 C(中锋)。但接下来的内容不涉及篮球比赛的细节。

第一行显示,亚特兰大老鹰队的大前锋 Paul Millsap 在 2015-2016 赛季的薪资接近 $\$18.7$ 百万美元。

[In ]:
from datascience import *
import numpy as np
path_data = '../../../assets/data/'
np.set_printoptions(threshold=50)
[In ]:
# This table can be found online: https://www.statcrunch.com/app/index.php?dataid=1843341
nba_salaries = Table.read_table(path_data + 'nba_salaries.csv')
nba_salaries
PLAYER           | POSITION | TEAM          | '15-'16 SALARY
Paul Millsap     | PF       | Atlanta Hawks | 18.6717
Al Horford       | C        | Atlanta Hawks | 12
Tiago Splitter   | C        | Atlanta Hawks | 9.75625
Jeff Teague      | PG       | Atlanta Hawks | 8
Kyle Korver      | SG       | Atlanta Hawks | 5.74648
Thabo Sefolosha  | SF       | Atlanta Hawks | 4
Mike Scott       | PF       | Atlanta Hawks | 3.33333
Kent Bazemore    | SF       | Atlanta Hawks | 2
Dennis Schroder  | PG       | Atlanta Hawks | 1.7634
Tim Hardaway Jr. | SG       | Atlanta Hawks | 1.30452
... (407 rows omitted)

该表格包含 417 行,每个球员一行。只显示了 10 行。show 方法允许我们指定行数,默认值(不指定)是表格的所有行。

[In ]:
nba_salaries.show(3)
<IPython.core.display.HTML object>

浏览大约 20 行左右,你会看到行是按球队名称的字母顺序排列的。也可以使用 sort 方法,按球员姓名字母顺序列出相同的行。sort 的参数是列标签或索引。

[In ]:
nba_salaries.sort('PLAYER').show(5)
<IPython.core.display.HTML object>

为了查看球员的薪资,如果数据按薪资排序会更有帮助。

为此,我们将首先简化薪资列的标签(仅为方便起见),然后按新标签 SALARY 排序。

这将按薪资递增顺序排列表格的所有行,最低薪资出现在最前面。输出是一个新表格,列与原表格相同,但行已重新排列。

[In ]:
nba = nba_salaries.relabeled("'15-'16 SALARY", 'SALARY')
nba.sort('SALARY')
PLAYER                 | POSITION | TEAM                 | SALARY
Thanasis Antetokounmpo | SF       | New York Knicks      | 0.030888
Jordan McRae           | SG       | Phoenix Suns         | 0.049709
Cory Jefferson         | PF       | Phoenix Suns         | 0.049709
Elliot Williams        | SG       | Memphis Grizzlies    | 0.055722
Orlando Johnson        | SG       | Phoenix Suns         | 0.055722
Phil Pressey           | PG       | Phoenix Suns         | 0.055722
Keith Appling          | PG       | Orlando Magic        | 0.061776
Sean Kilpatrick        | SG       | Denver Nuggets       | 0.099418
Erick Green            | PG       | Utah Jazz            | 0.099418
Jeff Ayres             | PF       | Los Angeles Clippers | 0.111444
... (407 rows omitted)

这些数字有些难以比较,因为一些球员在赛季中更换了球队,并从多支球队获得了薪资;表格中只显示来自最后一支球队的薪资。例如,控球后卫 Phil Pressey 在当年从费城转会到菲尼克斯,还可能再次转会到金州勇士队。

CNN 的报道关注的是薪资尺度的另一端——世界上薪资最高的球员。

要按薪资递减顺序排列表格的行,我们必须使用 sort 并带上选项 descending=True

[In ]:
nba.sort('SALARY', descending=True)
PLAYER          | POSITION | TEAM                  | SALARY
Kobe Bryant     | SF       | Los Angeles Lakers    | 25
Joe Johnson     | SF       | Brooklyn Nets         | 24.8949
LeBron James    | SF       | Cleveland Cavaliers   | 22.9705
Carmelo Anthony | SF       | New York Knicks       | 22.875
Dwight Howard   | C        | Houston Rockets       | 22.3594
Chris Bosh      | PF       | Miami Heat            | 22.1927
Chris Paul      | PG       | Los Angeles Clippers  | 21.4687
Kevin Durant    | SF       | Oklahoma City Thunder | 20.1586
Derrick Rose    | PG       | Chicago Bulls         | 20.0931
Dwyane Wade     | SG       | Miami Heat            | 20
... (407 rows omitted)

科比·布莱恩特(Kobe Bryant)在湖人的最后一个赛季,以 $\$25$ 百万美元的薪资成为最高薪球员。请注意,MVP 斯蒂芬·库里(Stephen Curry)并不在前 10 名中。他在榜单上的位置要靠后得多,我们稍后会看到。

命名参数

这个调用表达式中的 descending=True 部分称为命名参数。当调用函数或方法时,每个参数既有位置也有名称。这两者都可以从函数或方法的帮助文本中看出。

[In ]:
help(nba.sort)
Help on method sort in module datascience.tables:

sort(column_or_label, descending=False, distinct=False) method of datascience.tables.Table instance
    Return a Table of rows sorted according to the values in a column.
    
    Args:
        ``column_or_label``: the column whose values are used for sorting.
    
        ``descending``: if True, sorting will be in descending, rather than
            ascending order.
    
        ``distinct``: if True, repeated values in ``column_or_label`` will
            be omitted.
    
    Returns:
        An instance of ``Table`` containing rows sorted based on the values
        in ``column_or_label``.
    
    >>> marbles = Table().with_columns(
    ...    "Color", make_array("Red", "Green", "Blue", "Red", "Green", "Green"),
    ...    "Shape", make_array("Round", "Rectangular", "Rectangular", "Round", "Rectangular", "Round"),
    ...    "Amount", make_array(4, 6, 12, 7, 9, 2),
    ...    "Price", make_array(1.30, 1.30, 2.00, 1.75, 1.40, 1.00))
    >>> marbles
    Color | Shape       | Amount | Price
    Red   | Round       | 4      | 1.3
    Green | Rectangular | 6      | 1.3
    Blue  | Rectangular | 12     | 2
    Red   | Round       | 7      | 1.75
    Green | Rectangular | 9      | 1.4
    Green | Round       | 2      | 1
    >>> marbles.sort("Amount")
    Color | Shape       | Amount | Price
    Green | Round       | 2      | 1
    Red   | Round       | 4      | 1.3
    Green | Rectangular | 6      | 1.3
    Red   | Round       | 7      | 1.75
    Green | Rectangular | 9      | 1.4
    Blue  | Rectangular | 12     | 2
    >>> marbles.sort("Amount", descending = True)
    Color | Shape       | Amount | Price
    Blue  | Rectangular | 12     | 2
    Green | Rectangular | 9      | 1.4
    Red   | Round       | 7      | 1.75
    Green | Rectangular | 6      | 1.3
    Red   | Round       | 4      | 1.3
    Green | Round       | 2      | 1
    >>> marbles.sort(3) # the Price column
    Color | Shape       | Amount | Price
    Green | Round       | 2      | 1
    Red   | Round       | 4      | 1.3
    Green | Rectangular | 6      | 1.3
    Green | Rectangular | 9      | 1.4
    Red   | Round       | 7      | 1.75
    Blue  | Rectangular | 12     | 2
    >>> marbles.sort(3, distinct = True)
    Color | Shape       | Amount | Price
    Green | Round       | 2      | 1
    Red   | Round       | 4      | 1.3
    Green | Rectangular | 9      | 1.4
    Red   | Round       | 7      | 1.75
    Blue  | Rectangular | 12     | 2

在这段 help 文本的最顶部,出现了 sort 方法的签名

sort(column_or_label, descending=False, distinct=False)

这描述了 sort 三个参数的位置、名称和默认值。调用此方法时,可以使用位置参数或命名参数,因此以下三个调用完成完全相同的事情。

sort('SALARY', True)
sort('SALARY', descending=True)
sort(column_or_label='SALARY', descending=True)

当参数只是 TrueFalse 时,包含参数名称是一个有用的惯例,这样参数值的含义就更明显了。