HOWTO · Pandas

將兩個 Pandas 系列合併到一個 DataFrame 中

本指南演示瞭如何使用 pandas.concat()、pandas.merge()、DataFrame.join() 方法將兩個 Pandas 系列組合或合併到一個 DataFrame 中。

本頁內容

在 pandas 中,Series 是帶有標籤的一維陣列,大致可視為一個具有索引的資料欄。若要將兩個或多個 Series 合併成 DataFrame,請將它們傳給 pandas.concat() 並設定 axis=1;每個 Series 都會成為一欄,並以其名稱作為欄標題。若需要不同的語義,pandas.concat() 也能垂直堆疊 Series,pandas.merge() 會像 SQL 聯結一樣依索引比對資料列,而 DataFrame.join() 則可將具名 Series 附加到現有的 DataFrame。

本教學會透過可執行的範例逐一說明各種做法。

依據所需的結果選擇方法

這四種做法都會產生表格資料,但各自回答的問題不同:

  • pandas.concat([s1, s2], axis=1) 會將 Series 並排放置,使每個 Series 成為新 DataFrame 中的一欄。
  • pandas.concat([s1, s2]) 使用預設的 axis=0,會將 Series 堆疊成單一較長的 Series;若需要單欄 DataFrame,可將結果包進 pd.DataFrame()。這是目前取代 Series.append() 的做法,該方法已在 pandas 2.0 中移除。
  • pandas.merge(left, right, left_index=True, right_index=True) 會依索引或共用鍵值比對資料列,方式類似 SQL 聯結。
  • df.join(series) 會將具名 Series 加入你已有的 DataFrame,並依索引對齊。

這些方法有一項共同行為:pandas 會依索引對齊帶標籤的資料。當輸入的 Series 共用相同索引時,對齊過程並不明顯;當索引不同時,只存在於其中一個輸入的標籤會在合併結果中產生遺漏值(NaN)。

使用 pandas.concat() 將 Series 合併為欄

pandas.concat() 函式 會沿著軸串連 pandas 物件。傳入 axis=1 會將這些物件並排為欄;每個 Series 的名稱會成為欄標題,而資料列會依索引對齊。

執行下列範例:

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

# Create Series by assigning names
products = pd.Series(
    ["Intel Dell Laptops", "HP Laptops", "Lenavo Laptops", "Acer Laptops"],
    name="Products",
)
dollar_price = pd.Series([350, 300, 400, 250], name="Price")
percentage_sale = pd.Series([83, 99, 84, 76], name="Sale")

# merge three pandas series as columns using pandas.concat()
df = pd.concat([products, dollar_price, percentage_sale], axis=1)
print(df)

輸出:

             Products  Price  Sale
0  Intel Dell Laptops    350    83
1          HP Laptops    300    99
2      Lenavo Laptops    400    84
3        Acer Laptops    250    76

由於這三個 Series 共用預設的整數索引,資料列會依序對齊。若使用 axis=0(預設值),相同的呼叫會把值堆疊成一個長 Series,而不是建立欄。範例程式碼與輸出區塊保持原樣,因此其中顯示的欄名(例如 Products、Price、Sale、Skills)和註解會以英文呈現。

使用 pandas.concat() 垂直堆疊 Series

這項工作的舊版做法使用 Series.append(),它是一種沿 axis=0 串連的快捷方式。該方法在 pandas 1.4 中已被棄用,並在 pandas 2.0 中移除,因此現在呼叫它會產生 AttributeError。目前的替代做法是 pandas.concat():將 Series 放在清單中傳入,並設定 ignore_index=True,即可為合併後的結果重新編號。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

technical = pd.Series(["Pandas", "Python", "Scala", "Hadoop"])
non_technical = pd.Series(["SEO", "Graphic design", "Content writing", "Marketing"])

# stack the series and shape the result into a one-column DataFrame
df = pd.DataFrame(
    pd.concat([technical, non_technical], ignore_index=True), columns=["Skills"]
)
print(df)

輸出:

            Skills
0           Pandas
1           Python
2            Scala
3           Hadoop
4              SEO
5   Graphic design
6  Content writing
7        Marketing

在這裡,pd.concat() 會傳回包含八個值的單一 Series,而 pd.DataFrame(..., columns=["Skills"]) 會將它整理成單欄 DataFrame。若要保留原本的索引標籤而不是重新編號,請移除 ignore_index=True。

使用 pandas.merge() 依索引比對 Series

pandas.merge() 可在具名 Series 或 DataFrame 物件之間執行 SQL 風格的聯結。由於合併後的值會成為欄,每個 Series 都需要 name。設定 left_index=True 和 right_index=True 會指示 pandas.merge() 依索引而非某個鍵欄比對資料列。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

# Create Series by assigning names
products = pd.Series(
    ["Intel Dell Laptops", "HP Laptops", "Lenavo Laptops", "Acer Laptops"],
    name="Products",
)
dollar_price = pd.Series([350, 300, 400, 250], name="Price")

# match the two series on their index labels
df = pd.merge(products, dollar_price, right_index=True, left_index=True)
print(df)

輸出:

             Products  Price
0  Intel Dell Laptops    350
1          HP Laptops    300
2      Lenavo Laptops    400
3        Acer Laptops    250

預設聯結為 how="inner",因此只存在於其中一個 Series 的索引標籤會被排除在結果外;傳入 how="outer" 可保留所有標籤,並以 NaN 填補缺口。若要依值而非索引比對,請將 Series 轉換為 DataFrame,並將欄名傳給 on。

使用 DataFrame.join() 將 Series 聯結至 DataFrame

當其中一方已經是 DataFrame 時,DataFrame.join() 是最方便的選項。先用 pd.DataFrame() 轉換第一個 Series,再以第二個 Series 呼叫 .join();該 Series 必須具有 name,而這個名稱會成為新欄的標題。

本節中的程式碼以及顯示的標籤或輸出仍為英文。

import pandas as pd

# Create Series by assigning names
products = pd.Series(
    ["Intel Dell Laptops", "HP Laptops", "Lenavo Laptops", "Acer Laptops"],
    name="Products",
)
dollar_price = pd.Series([350, 300, 400, 250], name="Price")

# join the price series to a DataFrame built from products
df = pd.DataFrame(products).join(dollar_price)
print(df)

輸出:

             Products  Price
0  Intel Dell Laptops    350
1          HP Laptops    300
2      Lenavo Laptops    400
3        Acer Laptops    250

與 pandas.merge() 一樣,DataFrame.join() 會依索引對齊,但它預設使用左聯結,因此呼叫它的 DataFrame 中的每一列都會保留。

方法選擇總結:使用 pandas.concat() 搭配 axis=1,可從彼此獨立的 Series 建立 DataFrame;使用 pandas.concat() 沿 axis=0 堆疊,可完成過去由 Series.append() 執行的工作;當必須依索引或鍵值比對資料列時,使用 pandas.merge();若要將具名 Series 附加到已有的 DataFrame,則使用 DataFrame.join()。