1. 初始化兩個dataframe
df_left = pd.DataFrame(
columns=['no', 'name', 'age'],
data=[['111', 'Andy', 19], ['222', 'Bob', 20], ['333', 'Cindy', 21]]
)
df_right = pd.DataFrame(
columns=['key_no', 'remark'],
data=[['111', 'a'], ['111', 'b'], ['222', 'c']]
)
注意到,df_left
的no
列是唯一的,df_right
的key_no
列是有重複的
2. 合併兩個dataframe
res1 = pd.merge(left=df_left, right=df_right, left_on='no', right_on='key_no', how='left')
左連接merge兩個df時,生成的df出現了重複行,原因是:df_left
的no
列有一行值爲 111, df_right
的key_no
有兩行值爲 111,形成一對多
的關係,因此出現重複行。
這個問題在官方文檔也有提及到:
翻譯就是:
對重複鍵進行連接/合併可能導致返回的幀是行維度的乘法,這可能導致內存溢出。在加入大型 DataFrames 之前,用戶有責任管理鍵中的重複值。
3. 解決方式
3.1 解決方式1:
通過指定 validate='one_to_one'
If specified, checks if merge is of specified type.
- “one_to_one” or “1:1”: check if merge keys are unique in both left and right datasets.
- “one_to_many” or “1:m”: check if merge keys are unique in left dataset.
- “many_to_one” or “m:1”: check if merge keys are unique in right dataset.
- “many_to_many” or “m:m”: allowed, but does not result in checks.
如果拋異常,則說明沒有滿足一對一
關係,則需要進行去重處理,比如drop_duplicates
(要確保key重複時取哪個值)
例如:
from pandas.errors import MergeError
try:
res2 = pd.merge(left=df_left, right=df_right, left_on='no', right_on='key_no', how='left', validate='one_to_one')
except MergeError as e:
df_right = df_right.drop_duplicates(subset=['key_no']) # 對 key_no 列去重,保留第一次出現的結果作爲值
res2 = pd.merge(left=df_left, right=df_right, left_on='no', right_on='key_no', how='left', validate='one_to_one')
3.2 解決方式2
如果已經確定是一一對應的關係,則可以在 merge
前就進行一次去重處理即可,而不需要去處理異常
例如:
df_right = df_right.drop_duplicates(subset=['key_no'])
res2 = pd.merge(left=df_left, right=df_right, left_on='no', right_on='key_no', how='left', validate='one_to_one')