In [1]: import pandas as pd
本教程使用的数据
  • 本教程使用以 CSV 格式存储的泰坦尼克号数据集。该数据包含以下数据列:

    • PassengerId: 每位乘客的 ID。

    • Survived: 乘客是否存活的指示。 0 表示否,1 表示是。

    • Pclass: 三个船票等级之一:1 等,2 等,以及 3 等。

    • Name: 乘客姓名。

    • Sex: 乘客性别。

    • Age: 乘客年龄(以年为单位)。

    • SibSp: 船上的兄弟姐妹或配偶数量。

    • Parch: 船上的父母或子女数量。

    • Ticket: 乘客的船票号。

    • Fare: 票价。

    • Cabin: 乘客的客舱号。

    • Embarked: 登船港口。

    原始数据
    In [2]: titanic = pd.read_csv("data/titanic.csv")
    
    In [3]: titanic.head()
    Out[3]: 
       PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
    0            1         0       3  ...   7.2500   NaN         S
    1            2         1       1  ...  71.2833   C85         C
    2            3         1       3  ...   7.9250   NaN         S
    3            4         1       1  ...  53.1000  C123         S
    4            5         0       3  ...   8.0500   NaN         S
    
    [5 rows x 12 columns]
    

如何计算汇总统计信息#

汇总统计信息#

../../_images/06_aggregate.svg
  • 泰坦尼克号乘客的平均年龄是多少?

    In [4]: titanic["Age"].mean()
    Out[4]: np.float64(29.69911764705882)
    

有不同的统计信息可供选择,并可应用于包含数值数据的列。操作通常会排除缺失数据,并默认跨行进行。

../../_images/06_reduction.svg
  • 泰坦尼克号乘客的中位数年龄和船票价格是多少?

    In [5]: titanic[["Age", "Fare"]].median()
    Out[5]: 
    Age     28.0000
    Fare    14.4542
    dtype: float64
    

    应用于 DataFrame 中多个列的统计信息(选择两列会返回一个 DataFrame,请参阅 子集数据教程)将为每个数值列计算。

汇总统计信息可以同时为多个列计算。还记得 第一个教程 中的 describe 函数吗?

In [6]: titanic[["Age", "Fare"]].describe()
Out[6]: 
              Age        Fare
count  714.000000  891.000000
mean    29.699118   32.204208
std     14.526497   49.693429
min      0.420000    0.000000
25%     20.125000    7.910400
50%     28.000000   14.454200
75%     38.000000   31.000000
max     80.000000  512.329200

而不是使用预定义的统计信息,可以使用 DataFrame.agg() 方法定义给定列的特定汇总统计信息组合

In [7]: titanic.agg(
   ...:     {
   ...:         "Age": ["min", "max", "median", "skew"],
   ...:         "Fare": ["min", "max", "median", "mean"],
   ...:     }
   ...: )
   ...: 
Out[7]: 
              Age        Fare
min      0.420000    0.000000
max     80.000000  512.329200
median  28.000000   14.454200
skew     0.389108         NaN
mean          NaN   32.204208
用户指南

有关描述性统计信息的详细信息,请参阅用户指南中关于 描述性统计信息 的部分。

按类别汇总统计信息#

../../_images/06_groupby.svg
  • 男性与女性泰坦尼克号乘客的平均年龄是多少?

    In [8]: titanic[["Sex", "Age"]].groupby("Sex").mean()
    Out[8]: 
                  Age
    Sex              
    female  27.915709
    male    30.726645
    

    由于我们对每个性别的平均年龄感兴趣,因此首先对这两列进行子集选择:titanic[["Sex", "Age"]]。接下来,在 Sex 列上应用 groupby() 方法,为每个类别创建一个组。将计算并返回*每个性别*的平均年龄。

计算*一个列中每个类别*(例如,Sex 列中的男性/女性)的*给定统计信息*(例如,平均年龄)是一种常见的模式。使用 groupby 方法支持此类操作。这符合更通用的 split-apply-combine 模式

  • 拆分数据到组中

  • 独立地将函数应用于每个组

  • 结果合并到一个数据结构中

在 pandas 中,应用和合并步骤通常一起完成。

在前面的示例中,我们首先显式选择了 2 列。如果未这样做,通过传递 numeric_only=Truemean 方法将应用于包含数值列的每一列

In [9]: titanic.groupby("Sex").mean(numeric_only=True)
Out[9]: 
        PassengerId  Survived    Pclass  ...     SibSp     Parch       Fare
Sex                                      ...                               
female   431.028662  0.742038  2.159236  ...  0.694268  0.649682  44.479818
male     454.147314  0.188908  2.389948  ...  0.429809  0.235702  25.523893

[2 rows x 7 columns]

获取 Pclass 的平均值没有太大意义。如果我们只对每个性别的平均年龄感兴趣,也可以在分组数据上支持列的选择(一如既往地使用方括号 []

In [10]: titanic.groupby("Sex")["Age"].mean()
Out[10]: 
Sex
female    27.915709
male      30.726645
Name: Age, dtype: float64
../../_images/06_groupby_select_detail.svg

注意

Pclass 列包含数值数据,但实际上代表 3 个类别(或因子),分别带有标签“1”、“2”和“3”。计算这些的统计信息没有太大意义。因此,pandas 提供了 Categorical 数据类型来处理此类数据。有关详细信息,请参阅用户指南的 分类数据 部分。

  • 每个性别和客舱组合的平均船票价格是多少?

    In [11]: titanic.groupby(["Sex", "Pclass"])["Fare"].mean()
    Out[11]: 
    Sex     Pclass
    female  1         106.125798
            2          21.970121
            3          16.118810
    male    1          67.226127
            2          19.741782
            3          12.661633
    Name: Fare, dtype: float64
    

    可以同时按多个列进行分组。将列名作为列表传递给 groupby() 方法。

用户指南

有关 split-apply-combine 方法的完整描述,请参阅用户指南中关于 groupby 操作 的部分。

按类别计算记录数#

../../_images/06_valuecounts.svg
  • 每个客舱的乘客人数是多少?

    In [12]: titanic["Pclass"].value_counts()
    Out[12]: 
    Pclass
    3    491
    1    216
    2    184
    Name: count, dtype: int64
    

    value_counts() 方法计算列中每个类别的记录数。

该函数是一个快捷方式,实际上是 groupby 操作与计算每个组内的记录数相结合

In [13]: titanic.groupby("Pclass")["Pclass"].count()
Out[13]: 
Pclass
1    216
2    184
3    491
Name: Pclass, dtype: int64

注意

可以使用 sizecount 结合 groupby 使用。其中 size 包括 NaN 值并仅提供行数(表的大小),而 count 则排除缺失值。在 value_counts 方法中,使用 dropna 参数来包含或排除 NaN 值。

用户指南

用户指南有一个关于 value_counts 的专门部分,请参阅关于 离散化 的页面。

请记住

  • 可以对整个列或行计算聚合统计信息。

  • groupby 提供了split-apply-combine 模式的强大功能。

  • value_counts 是一个方便的快捷方式,用于计算变量每个类别中的条目数。

用户指南

有关 split-apply-combine 方法的完整描述,请参阅用户指南中关于 groupby 操作 的页面。