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

    • PassengerId:每位乘客的 ID。

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

    • Pclass:3 种票类之一:Class 1、Class 2 和 Class 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]
    

如何选择 DataFrame 的子集?#

如何从 DataFrame 中选择特定列?#

../../_images/03_subset_columns.svg
  • 我对泰坦尼克号乘客的年龄感兴趣。

    In [4]: ages = titanic["Age"]
    
    In [5]: ages.head()
    Out[5]: 
    0    22.0
    1    38.0
    2    26.0
    3    35.0
    4    35.0
    Name: Age, dtype: float64
    

    要选择单个列,请使用方括号 [] 并指定感兴趣的列名。

DataFrame 中的每个列都是一个 Series。当选择单个列时,返回的对象是一个 pandas Series。我们可以通过检查输出的类型来验证这一点。

In [6]: type(titanic["Age"])
Out[6]: pandas.core.series.Series

并查看输出的 shape

In [7]: titanic["Age"].shape
Out[7]: (891,)

DataFrame.shape 是 pandas SeriesDataFrame 的一个属性(请记住读写教程,属性不使用括号),它包含行数和列数:(nrows, ncolumns)。pandas Series 是一维的,只返回行数。

  • 我对泰坦尼克号乘客的年龄和性别感兴趣。

    In [8]: age_sex = titanic[["Age", "Sex"]]
    
    In [9]: age_sex.head()
    Out[9]: 
        Age     Sex
    0  22.0    male
    1  38.0  female
    2  26.0  female
    3  35.0  female
    4  35.0    male
    

    要选择多个列,请在选择括号 [] 中使用列名列表。

注意

内部方括号定义了一个包含列名的 Python 列表,而外部方括号用于从 pandas DataFrame 中选择数据,如前面的示例所示。

返回的数据类型是 pandas DataFrame

In [10]: type(titanic[["Age", "Sex"]])
Out[10]: pandas.core.frame.DataFrame
In [11]: titanic[["Age", "Sex"]].shape
Out[11]: (891, 2)

该选择返回了一个包含 891 行和 2 列的 DataFrame。请记住,DataFrame 是二维的,具有行和列两个维度。

用户指南

有关索引的基本信息,请参阅用户指南中关于索引和选择数据的部分。

如何从 DataFrame 中筛选特定行?#

../../_images/03_subset_rows.svg
  • 我对年龄大于 35 岁的乘客感兴趣。

    In [12]: above_35 = titanic[titanic["Age"] > 35]
    
    In [13]: above_35.head()
    Out[13]: 
        PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
    1             2         1       1  ...  71.2833   C85         C
    6             7         0       1  ...  51.8625   E46         S
    11           12         1       1  ...  26.5500  C103         S
    13           14         0       3  ...  31.2750   NaN         S
    15           16         1       2  ...  16.0000   NaN         S
    
    [5 rows x 12 columns]
    

    要根据条件表达式选择行,请在选择括号 [] 中使用条件。

选择括号 [] 内的条件 titanic["Age"] > 35 检查 Age 列中值大于 35 的行。

In [14]: titanic["Age"] > 35
Out[14]: 
0      False
1       True
2      False
3      False
4      False
       ...  
886    False
887    False
888    False
889    False
890    False
Name: Age, Length: 891, dtype: bool

条件表达式(>,但 ==, !=, <, <= 等也同样适用)的输出实际上是一个布尔值(TrueFalse)的 pandas Series,其行数与原始 DataFrame 相同。这种布尔值的 Series 可以通过将其放入选择括号 [] 中来筛选 DataFrame。只有值为 True 的行才会被选中。

我们之前知道原始的泰坦尼克号 DataFrame 包含 891 行。让我们通过检查结果 DataFrame above_35shape 属性来查看满足条件的行数。

In [15]: above_35.shape
Out[15]: (217, 12)
  • 我对泰坦尼克号中舱位等级为 2 和 3 的乘客感兴趣。

    In [16]: class_23 = titanic[titanic["Pclass"].isin([2, 3])]
    
    In [17]: class_23.head()
    Out[17]: 
       PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
    0            1         0       3  ...   7.2500   NaN         S
    2            3         1       3  ...   7.9250   NaN         S
    4            5         0       3  ...   8.0500   NaN         S
    5            6         0       3  ...   8.4583   NaN         Q
    7            8         0       3  ...  21.0750   NaN         S
    
    [5 rows x 12 columns]
    

    与条件表达式类似,isin() 条件函数对于提供列表中包含值的每一行返回 True。要根据此类函数筛选行,请在选择括号 [] 中使用条件函数。在这种情况下,选择括号中的条件 titanic["Pclass"].isin([2, 3]) 检查 Pclass 列的值是 2 还是 3 的行。

上述操作等同于筛选类别为 2 或 3 的行,并将这两个语句与 | (或) 运算符结合使用。

In [18]: class_23 = titanic[(titanic["Pclass"] == 2) | (titanic["Pclass"] == 3)]

In [19]: class_23.head()
Out[19]: 
   PassengerId  Survived  Pclass  ...     Fare Cabin  Embarked
0            1         0       3  ...   7.2500   NaN         S
2            3         1       3  ...   7.9250   NaN         S
4            5         0       3  ...   8.0500   NaN         S
5            6         0       3  ...   8.4583   NaN         Q
7            8         0       3  ...  21.0750   NaN         S

[5 rows x 12 columns]

注意

组合多个条件语句时,每个条件必须用括号 () 括起来。此外,不能使用 or/and,而需要使用 or 运算符 |and 运算符 &

用户指南

请参阅用户指南中关于布尔索引isin 函数的专门部分。

  • 我希望处理年龄已知的乘客数据。

    In [20]: age_no_na = titanic[titanic["Age"].notna()]
    
    In [21]: age_no_na.head()
    Out[21]: 
       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]
    

    notna() 条件函数对于值不是 Null 值的每一行返回 True。因此,它可以与选择括号 [] 结合使用来筛选数据表。

您可能想知道实际上有什么变化,因为前 5 行的值仍然相同。一种验证方法是检查 shape 是否已更改。

In [22]: age_no_na.shape
Out[22]: (714, 12)
用户指南

有关缺失值的更多专用函数,请参阅用户指南中关于处理缺失数据的部分。

如何从 DataFrame 中选择特定行和列?#

../../_images/03_subset_columns_rows.svg
  • 我对年龄大于 35 岁的乘客姓名感兴趣。

    In [23]: adult_names = titanic.loc[titanic["Age"] > 35, "Name"]
    
    In [24]: adult_names.head()
    Out[24]: 
    1     Cumings, Mrs. John Bradley (Florence Briggs Th...
    6                               McCarthy, Mr. Timothy J
    11                             Bonnell, Miss. Elizabeth
    13                          Andersson, Mr. Anders Johan
    15                     Hewlett, Mrs. (Mary D Kingcome) 
    Name: Name, dtype: object
    

    在这种情况下,需要一次性创建行和列的子集,仅仅使用选择括号 [] 已不再足够。需要在选择括号 [] 前面使用 loc/iloc 运算符。当使用 loc/iloc 时,逗号前是您想要的行,逗号后是您想要选择的列。

当使用列名、行标签或条件表达式时,请在选择括号 [] 前使用 loc 运算符。对于逗号前和逗号后的部分,您可以使用单个标签、标签列表、标签切片、条件表达式或冒号。使用冒号表示您希望选择所有行或所有列。

  • 我对第 10 到 25 行以及第 3 到 5 列感兴趣。

    In [25]: titanic.iloc[9:25, 2:5]
    Out[25]: 
        Pclass                                 Name     Sex
    9        2  Nasser, Mrs. Nicholas (Adele Achem)  female
    10       3      Sandstrom, Miss. Marguerite Rut  female
    11       1             Bonnell, Miss. Elizabeth  female
    12       3       Saundercock, Mr. William Henry    male
    13       3          Andersson, Mr. Anders Johan    male
    ..     ...                                  ...     ...
    20       2                 Fynney, Mr. Joseph J    male
    21       2                Beesley, Mr. Lawrence    male
    22       3          McGowan, Miss. Anna "Annie"  female
    23       1         Sloper, Mr. William Thompson    male
    24       3        Palsson, Miss. Torborg Danira  female
    
    [16 rows x 3 columns]
    

    同样,行和列的子集是一次性创建的,仅仅使用选择括号 [] 已不再足够。当您特别关注表中特定位置的某些行和/或列时,请在选择括号 [] 前使用 iloc 运算符。

当使用 lociloc 选择特定行和/或列时,可以将新值分配给所选数据。例如,将名称 anonymous 分配给第四列的前 3 个元素。

In [26]: titanic.iloc[0:3, 3] = "anonymous"

In [27]: titanic.head()
Out[27]: 
   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]
用户指南

请参阅用户指南中关于不同索引选择的部分,以更深入地了解 lociloc 的用法。

请记住

  • 选择数据子集时,使用方括号 []

  • 在这些括号内,您可以使用单个列/行标签、列/行标签列表、标签切片、条件表达式或冒号。

  • 当使用行和列名时,使用 loc 选择特定行和/或列。

  • 当使用表中位置时,使用 iloc 选择特定行和/或列。

  • 您可以根据 loc/iloc 为选择的数据分配新值。

用户指南

有关索引的完整概述,请参阅用户指南中关于索引和选择数据的页面。