In [1]: import pandas as pd
本教學課程使用資料
  • 本教學課程使用以 CSV 儲存的鐵達尼號資料集。資料包含下列資料欄位

    • PassengerId:每位乘客的 ID。

    • Survived:表示乘客是否倖存。是為 0,否為 1

    • Pclass:3 種票艙等級之一:艙等 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]
    

如何選取 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 的屬性(請記住 關於讀取和寫入的教學,不要對屬性使用括號),其中包含列數和欄位數:(列數, 欄位數)。pandas Series 是 1 維的,因此只會傳回列數。

  • 我對鐵達尼號乘客的年齡和性別有興趣。

    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

條件表達式的輸出(>,但還有 ==!=<<= 等會運作)實際上是 pandas Series 的布林值(TrueFalse)系列,其列數與原始 DataFrame 相同。此類布林值的 Series 可用於篩選 DataFrame,方法是將其置於選取括號 [] 之間。僅會選取值為 True 的列。

我們從前面得知,原始的 Titanic DataFrame 包含 891 列。讓我們透過查看結果 DataFrame above_35shape 屬性,來看看符合條件的列數。

In [15]: above_35.shape
Out[15]: (217, 12)
  • 我對艙等為 2 和 3 的 Titanic 乘客感興趣。

    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 列仍然是相同的數值。驗證的方法之一是檢查形狀是否已改變

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 為選取項目指定新值。

至使用者指南

索引和選取資料 的使用者指南頁面中提供了索引的完整概觀。