Pandas 提供了強大的資料合併功能,pd.merge 函式允許開發者根據指定的鍵值合併 DataFrame 物件。這對於整合不同來源的資料至關重要,例如將使用者資訊與交易記錄合併,或是整合不同時間段的銷售資料。合併時可以選擇不同的合併方式,例如內部合併、外部合併、左合併和右合併,以控制合併結果中資料的保留方式。開發者可以根據需求選擇合適的合併方式,確保資料的完整性和準確性。此外,pd.merge 還支援多鍵值合併,可以根據多個欄位進行匹配,提高合併的精確度。
合併DataFrame物件:使用pd.merge的技術解析
在資料重塑的過程中,合併(merge)或聯結(join)是常見的操作,尤其是在資料函式庫領域中。本文將探討pandas函式庫中的pd.merge方法,並透過實際範例展示如何有效地合併DataFrame物件。
為何需要合併DataFrame物件?
在處理資料時,我們經常需要將不同來源的資料集合併,以獲得更全面的分析結果。pd.merge提供了一種靈活的方式,根據指定的鍵(key)將兩個DataFrame物件合併。
使用pd.merge進行合併操作
首先,我們建立兩個範例DataFrame物件,分別代表第一季(Q1)和第二季(Q2)的股票交易資料:
import pandas as pd
# 建立第一季(Q1)的DataFrame
df_q1 = pd.DataFrame([
["AAPL", 100., 50., 75.],
["MSFT", 80., 42., 62.],
["AMZN", 60., 100., 120.],
], columns=["ticker", "shares", "low", "high"])
# 資料型別轉換
df_q1 = df_q1.convert_dtypes(dtype_backend="numpy_nullable")
# 建立第二季(Q2)的DataFrame
df_q2 = pd.DataFrame([
["AAPL", 80., 70., 80., 77.],
["MSFT", 90., 50., 60., 55.],
["IBM", 100., 60., 70., 64.],
["GE", 42., 30., 50., 44.],
], columns=["ticker", "shares", "low", "high", "close"])
# 資料型別轉換
df_q2 = df_q2.convert_dtypes(dtype_backend="numpy_nullable")
合併DataFrame物件
使用pd.merge可以根據指定的鍵(此例中為ticker欄位)合併兩個DataFrame物件:
# 使用內部合併(inner merge)
merged_df = pd.merge(df_q1, df_q2, on=["ticker"])
#### 內容解密:
pd.merge(df_q1, df_q2, on=["ticker"]):根據ticker欄位合併df_q1和df_q2。on=["ticker"]引數指定了用於合併的鍵。- 預設情況下,
pd.merge執行內部合併(inner merge),僅保留兩個DataFrame中鍵匹配的行。
合併行為控制:how引數
pd.merge提供了多種合併行為,透過how引數控制:
- 內部合併(inner merge):預設行為,僅保留鍵匹配的行。
- 外部合併(outer merge):保留兩個DataFrame中的所有行。
- 左側合併(left merge):保留左側DataFrame的所有行,並根據鍵匹配右側DataFrame的資料。
- 右側合併(right merge):與左側合併相反,保留右側DataFrame的所有行。
# 外部合併範例
merged_df_outer = pd.merge(df_q1, df_q2, on=["ticker"], how="outer")
#### 內容解密:
how="outer"引數指定了外部合併,保留兩個DataFrame中的所有行。- 若某一行在另一個DataFrame中沒有匹配的鍵,則對應的欄位將以
<NA>填充。
自定義字尾:suffixes引數
當兩個DataFrame中有相同名稱的欄位時,pd.merge會自動新增字尾以區分。可以透過suffixes引數自定義字尾:
# 自定義字尾範例
merged_df_suffix = pd.merge(
df_q1,
df_q2,
on=["ticker"],
how="outer",
suffixes=("_q1", "_q2"),
)
#### 內容解密:
suffixes=("_q1", "_q2")引數自定義了字尾,分別為_q1和_q2,以區分來自不同季度的資料。
合併結果分析與指標
使用indicator=True引數,可以在結果DataFrame中新增一欄,指示每一行的來源:
# 新增來源指標範例
merged_df_indicator = pd.merge(df_q1, df_q2, on=["ticker"], how="outer", indicator=True)
#### 內容解密:
indicator=True引數在結果DataFrame中增加了_merge欄位,指示每一行的來源。_merge欄位的值包括both、left_only和right_only,分別表示該行在兩個DataFrame中都有、在左側DataFrame、在右側DataFrame。
資料框架合併的深度解析
在資料分析與處理的過程中,合併不同來源的資料是一個常見且重要的任務。Pandas 函式庫中的 pd.merge 函式提供了強大的合併功能,使得我們能夠根據特定的鍵值(key)將兩個資料框架(DataFrame)進行合併。
合併的基本概念
當我們需要合併兩個資料框架時,通常會根據一個或多個共同的欄位進行匹配。這些欄位被稱為鍵值或合併鍵。在 pd.merge 中,我們可以透過 on 引數指定這些鍵值。
簡單合併範例
假設我們有兩個資料框架 df_q1 和 df_q2,它們分別代表了第一季度和第二季度的股票交易資料。
import pandas as pd
# 建立第一季度的資料框架
df_q1 = pd.DataFrame({
"ticker": ["AAPL", "AMZN", "GE", "IBM", "MSFT"],
"shares": [100, 60, None, None, 80],
"low": [50, 100, None, None, 42],
"high": [None, None, 555.0, 555.0, 555.0]
})
# 建立第二季度的資料框架
df_q2 = pd.DataFrame({
"ticker": ["AAPL", "MSFT", "IBM", "GE"],
"shares": [80, 90, 100, 42],
"low": [70, 50, 60, 30],
"high": [80, 60, 70, 50],
"close": [77, 55, 64, 44]
})
# 對 df_q2 的 ticker 欄位進行重新命名
df_q2 = df_q2.rename(columns={"ticker": "SYMBOL"})
# 使用 pd.merge 合併 df_q1 和 df_q2
merged_df = pd.merge(
df_q1,
df_q2,
left_on=["ticker"],
right_on=["SYMBOL"],
how="outer",
suffixes=("_q1", "_q2")
)
print(merged_df)
輸出結果
| ticker | shares_q1 | low_q1 | high_q1 | SYMBOL | shares_q2 | low_q2 | high_q2 | close |
|---|---|---|---|---|---|---|---|---|
| AAPL | 100.0 | 50.0 | None | AAPL | 80 | 70 | 80 | 77 |
| AMZN | 60.0 | 100.0 | None | None | None | None | None | None |
| None | None | None | None | GE | 42 | 30 | 50 | 44 |
| None | None | None | None | IBM | 100 | 60 | 70 | 64 |
| MSFT | 80.0 | 42.0 | 555.0 | MSFT | 90 | 50 | 60 | 55 |
多鍵值合併
在某些情況下,我們需要根據多個欄位進行合併。以下範例展示瞭如何根據 ticker 和 quarter 兩個欄位進行合併。
# 建立低價資料框架
lows = pd.DataFrame({
"ticker": ["AAPL", "MSFT", "AMZN", "AAPL", "MSFT", "IBM", "GE"],
"quarter": ["Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q2"],
"low": [50., 42., 100., 70., 50., 60., 30.]
})
# 建立高價資料框架
highs = pd.DataFrame({
"SYMBOL": ["AAPL", "MSFT", "AMZN", "AAPL", "MSFT", "IBM", "GE"],
"QTR": ["Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q2"],
"high": [75., 62., 120., 80., 60., 70., 50.]
})
# 合併低價和高價資料框架
merged_df = pd.merge(
lows,
highs,
left_on=["ticker", "quarter"],
right_on=["SYMBOL", "QTR"]
)
print(merged_df)
輸出結果
| ticker | quarter | low | SYMBOL | QTR | high |
|---|---|---|---|---|---|
| AAPL | Q1 | 50.0 | AAPL | Q1 | 75.0 |
| MSFT | Q1 | 42.0 | MSFT | Q1 | 62.0 |
| AMZN | Q1 | 100.0 | AMZN | Q1 | 120.0 |
| AAPL | Q2 | 70.0 | AAPL | Q2 | 80.0 |
| MSFT | Q2 | 50.0 | MSFT | Q2 | 60.0 |
| IBM | Q2 | 60.0 | IBM | Q2 | 70.0 |
| GE | Q2 | 30.0 | GE | Q2 | 50.0 |
合併關係的驗證
在進行合併時,瞭解兩個資料框架之間的關係至關重要。pd.merge 提供了一個 validate引數,用於驗證合併鍵之間的關係。
# 銷售資料框架
sales = pd.DataFrame({
"month": ["Jan", "Feb", "Mar"],
"salesperson": ["John", "John", "John"],
"sales": [10, 20, 30]
})
# 地區資料框架
regions = pd.DataFrame({
"salesperson": ["John", "Jane"],
"region": ["Northeast", "Southwest"]
})
# 合併銷售和地區資料框架
merged_df = pd.merge(sales, regions, on=["salesperson"], validate="many_to_one")
print(merged_df)
輸出結果
| month | salesperson | sales | region |
|---|---|---|---|
| Jan | John | 10 | Northeast |
| Feb | John | 20 | Northeast |
| Mar | John |
程式碼詳解:
- 建立 DataFrame:首先,我們建立了兩個 DataFrame,分別代表第一季度和第二季度的股票交易資料。
- 重新命名欄位:為了展示如何處理不同名稱的合併鍵,我們對第二季度的 DataFrame 中的
ticker欄位重新命名為SYMBOL。 - 使用
pd.merge合併:利用pd.merge將兩個 DataFrame 合併,指定左側 DataFrame 的ticker欄位和右側 DataFrame 的SYMBOL欄位作為合併鍵。 - 多鍵值合併:進一步展示瞭如何根據多個欄位(如
ticker和quarter)進行合併。 - 驗證合併關係:最後,透過
validate引數驗證了合併鍵之間的關係,確保資料的正確性。
重塑DataFrame的藝術
在資料分析的世界中,資料的形狀和結構往往決定了分析的難易程度和結果的可讀性。Pandas函式庫中的pd.merge、pd.DataFrame.join、pd.DataFrame.stack和pd.DataFrame.unstack等方法,為我們提供了強大的資料重塑工具。
合併DataFrame:pd.merge vs pd.DataFrame.join
當我們需要將兩個DataFrame合併時,pd.merge和pd.DataFrame.join是兩個常用的方法。雖然它們在功能上相似,但在使用場景和風格上有所不同。
為什麼選擇pd.merge或pd.DataFrame.join?
- 當兩個DataFrame具有相同的合併依據(例如,某一列或索引),且需要根據特定的合併策略(例如,內連線、左連線等)進行合併時,可以使用
pd.merge。 - 當需要將一個DataFrame的列新增到另一個DataFrame中,且主要DataFrame的索引與輔助DataFrame的索引相匹配時,
pd.DataFrame.join提供了一個更簡潔的語法。
例項解析
假設我們有一個銷售資料表sales和一個業務人員後設資料表salesperson,兩者都透過salesperson_id索引相關聯。
# 銷售資料表
sales = pd.DataFrame(
[[1000], [2000], [4000]],
columns=["sales"],
index=pd.Index([42, 555, 9000], name="salesperson_id")
)
# 業務人員後設資料表
salesperson = pd.DataFrame([
["Jane", "Doe"],
["John", "Smith"],
], columns=["first_name", "last_name"], index=pd.Index(
[42, 555], name="salesperson_id"
))
# 使用pd.merge進行左連線
merged_df = pd.merge(sales, salesperson, left_index=True, right_index=True, how="left")
# 使用pd.DataFrame.join進行左連線
joined_df = sales.join(salesperson)
程式碼解密:
- 建立DataFrame:首先,我們建立了兩個DataFrame:
sales和salesperson。這兩個DataFrame都使用了salesperson_id作為索引。 pd.merge的使用:透過指定left_index=True和right_index=True,我們告訴pd.merge使用索引作為合併的依據。引數how="left"確保了sales表中的所有記錄都被保留。pd.DataFrame.join的使用:sales.join(salesperson)實作了與上述pd.merge呼叫相同的功能,但語法更簡潔。預設情況下,pd.DataFrame.join執行左連線。- 結果比較:兩種方法都將
salesperson表的列新增到sales表中,並根據索引進行匹配。對於在salesperson表中沒有對應記錄的sales表中的行(例如,salesperson_id為9000),結果中將顯示<NA>。
重塑DataFrame:從寬格式到長格式
在資料分析中,我們經常需要在寬格式和長格式之間轉換資料。寬格式資料的特點是每個變數佔據一列,而長格式資料則透過增加行數來表示不同的變數。
pd.DataFrame.stack和pd.DataFrame.unstack的使用
pd.DataFrame.stack:將DataFrame從寬格式轉換為長格式,即將列「堆積疊」到行中。pd.DataFrame.unstack:將DataFrame從長格式轉換為寬格式,即將行「展開」到列中。
圖表說明:
graph LR
A[寬格式] -->|stack|> B[長格式]
B -->|unstack|> A
圖表翻譯: 此圖示展示了寬格式與長格式之間的轉換關係。透過 stack 方法,可以將寬格式資料轉換為長格式;反之,透過 unstack 方法,可以將長格式資料轉換回寬格式。
例項解析
假設我們有一個水果產量匯總表,記錄了不同州的水果產量。
df = pd.DataFrame([
[12, 10, 40],
[9, 7, 12],
[0, 14, 190]
], columns=pd.Index(["Apple", "Orange", "Banana"], name="fruit"), index=pd.Index(
["Texas", "Arizona", "Florida"], name="state"))
# 將DataFrame從寬格式轉換為長格式
long_df = df.stack()
# 將DataFrame從長格式轉換回寬格式
wide_df = long_df.unstack()
程式碼解密:
- 建立水果產量表:首先,我們建立了一個DataFrame
df,其中包含了不同州的水果產量。 stack()方法的使用:呼叫df.stack()將DataFrame從寬格式轉換為長格式。在這個過程中,原本作為列的水果名稱被「堆積疊」到了行索引中,形成了一個多級索引的Series。unstack()方法的使用:對得到的長格式Series呼叫.unstack(),可以將其轉換回寬格式的DataFrame。