ความแตกต่างระหว่าง merge () และ concat () ในแพนด้า


89

อะไรคือความแตกต่างที่สำคัญระหว่างpd.DataFrame.merge()และpd.concat()?

จนถึงตอนนี้นี่คือสิ่งที่ฉันพบโปรดแสดงความคิดเห็นว่าความเข้าใจของฉันสมบูรณ์และถูกต้องเพียงใด:

  • .merge()สามารถใช้ได้เฉพาะคอลัมน์ (บวกดัชนีแถว) และเหมาะสำหรับการดำเนินการในรูปแบบฐานข้อมูล .concat()สามารถใช้ได้กับแกนใดแกนหนึ่งโดยใช้เฉพาะดัชนีและมีตัวเลือกในการเพิ่มดัชนีตามลำดับชั้น

  • อนึ่งสิ่งนี้ทำให้เกิดความซ้ำซ้อนดังต่อไปนี้: ทั้งสองสามารถรวมสอง dataframes โดยใช้ดัชนีแถว

  • pd.DataFrame.join() เพียงเสนอชวเลขสำหรับบางกรณีการใช้งานของ .merge()

(หมีแพนด้าเก่งมากในการจัดการกรณีการใช้งานที่หลากหลายในการวิเคราะห์ข้อมูลอาจเป็นเรื่องที่น่ากังวลเล็กน้อยในการสำรวจเอกสารเพื่อหาวิธีที่ดีที่สุดในการทำงานบางอย่าง)


3
นอกจากนี้ที่เกี่ยวข้อง: stackoverflow.com/a/37891437/1972495การสนทนารอบ.merge()และ.join().
WindChimes

2
เมื่อผสานเข้าร่วมและเชื่อมต่อฉันพบว่าคำตอบนี้ชัดเจนมากว่าพวกเขาทั้งหมดสามารถใช้ทำสิ่งเดียวกันได้อย่างไร (ดูเหมือนจะเป็นเพียงอินเทอร์เฟซทางเลือกสำหรับฟังก์ชันเดียวกัน) ขอบคุณคำถามของคุณ (และคำตอบที่คุณเชื่อมโยงในความคิดเห็น) ในที่สุดฉันก็เข้าใจว่าการผสานและการเข้าร่วมเกี่ยวข้องกันอย่างไร ยังไม่ชัดเจนสำหรับฉันว่า concat ใช้การใช้งานที่แตกต่างกันหรือไม่ (ฉันเดาว่าฉันจะต้องดูซอร์สโค้ด ... )
pietroppeter

คำตอบ:


79

ความแตกต่างระดับที่สูงมากmerge()คือการใช้เพื่อรวมสอง (หรือมากกว่า) เฟรมข้อมูลบนพื้นฐานของค่าของคอลัมน์ทั่วไป (ดัชนีสามารถใช้ใช้left_index=Trueและ / หรือright_index=True) และconcat()ใช้เพื่อต่อท้ายเฟรมข้อมูลหนึ่ง (หรือมากกว่า) หนึ่ง ด้านล่างอีกด้านหนึ่ง (หรือด้านข้างขึ้นอยู่กับว่าaxisตั้งค่าตัวเลือกเป็น 0 หรือ 1)

join()ใช้เพื่อผสาน 2 dataframes บนพื้นฐานของดัชนี แทนที่จะใช้merge()กับตัวเลือกที่left_index=Trueเราสามารถjoin()ใช้ได้

ตัวอย่างเช่น:

df1 = pd.DataFrame({'Key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], 'data1': range(7)})

df1:
   Key  data1
0   b   0
1   b   1
2   a   2
3   c   3
4   a   4
5   a   5
6   b   6

df2 = pd.DataFrame({'Key': ['a', 'b', 'd'], 'data2': range(3)})

df2:
    Key data2
0   a   0
1   b   1
2   d   2

#Merge
# The 2 dataframes are merged on the basis of values in column "Key" as it is 
# a common column in 2 dataframes

pd.merge(df1, df2)

   Key data1 data2
0   b    0    1
1   b    1    1
2   b    6    1
3   a    2    0
4   a    4    0
5   a    5    0

#Concat
# df2 dataframe is appended at the bottom of df1 

pd.concat([df1, df2])

   Key data1 data2
0   b   0     NaN
1   b   1     NaN
2   a   2     NaN
3   c   3     NaN
4   a   4     NaN
5   a   5     NaN
6   b   6     NaN
0   a   Nan   0
1   b   Nan   1
2   d   Nan   2

ดังนั้นนี่หมายความว่าการโต้แย้งhowในการmergeทำงานและความหมายแตกต่างกันโดยสิ้นเชิงกับสิ่งที่เกิดขึ้นconcat?
Hemanth Bakaya

11

pd.concatใช้Iterableเป็นอาร์กิวเมนต์ ดังนั้นจึงไม่สามารถใช้DataFrames โดยตรงเป็นอาร์กิวเมนต์ นอกจากนี้ยังDimensions ของDataFrameควรจะตรงตามแนวแกนในขณะที่เชื่อมโยง

pd.mergeสามารถใช้DataFrames เป็นอาร์กิวเมนต์และใช้เพื่อรวมสองDataFrames ที่มีคอลัมน์หรือดัชนีเดียวกันซึ่งไม่สามารถทำได้pd.concatเนื่องจากจะแสดงคอลัมน์ที่ซ้ำกันใน DataFrame

ในขณะที่การเข้าร่วมสามารถใช้เพื่อเข้าร่วมสองDataFrames ที่มีดัชนีต่างกัน


7
ฉันชอบคำตอบนี้เพราะระบุว่ามิติข้อมูลควรตรงกันเมื่อเชื่อมต่อกัน concatไม่มีอะไรมากไปกว่าการติดกาวดาต้าเฟรมหลาย ๆ อันที่ด้านบนของ / ข้างๆกัน ไม่มีเนื้อหาที่ทราบในแง่ที่ว่าจะแสดงคอลัมน์เดียวกันสองครั้ง ในขณะที่mergeจริงๆแล้วจะรวมคอลัมน์เมื่อเหมือนกัน
jorijnsmit

3
คิดว่าไม่จริงค่ะ แม้แต่คำตอบข้างต้น (โดย @Abhishek Sawant) ก็ยกตัวอย่างconcatว่ามิติข้อมูลไม่ตรงกัน
michcio1234

8

ฉันกำลังพยายามทำความเข้าใจความแตกต่างที่สำคัญระหว่างpd.DataFrame.merge()และpd.concat()และ

เป็นคำถามที่ดี ความแตกต่างหลัก:

pd.concat ทำงานได้ทั้งสองแกน

ความแตกต่างอื่น ๆ คือpd.concatมีการรวมเริ่มต้นภายในและการรวมภายนอกเท่านั้นในขณะที่มีการรวมเริ่มต้นด้านซ้าย , ขวา , ด้านนอก , ด้านในpd.DataFrame.merge()

ความแตกต่างที่น่าสังเกตประการที่สามคือ: pd.DataFrame.merge()มีตัวเลือกในการตั้งค่าส่วนต่อท้ายคอลัมน์เมื่อรวมคอลัมน์ที่มีชื่อเดียวกันในขณะที่pd.concatไม่สามารถทำได้


ด้วยpd.concatค่าเริ่มต้นคุณจะสามารถซ้อนแถวของดาต้าเฟรมหลายแถว ( axis=0) และเมื่อคุณตั้งค่าaxis=1จากนั้นคุณจะเลียนแบบpd.DataFrame.merge()ฟังก์ชัน

ตัวอย่างที่เป็นประโยชน์ของpd.concat:

df2=pd.concat([df]*2, ignore_index=True) #double the rows of a dataframe

df2=pd.concat([df, df.iloc[[0]]]) # add first row to the end

df3=pd.concat([df1,df2], join='inner', ignore_index=True) # concat two df's

ในการpd.concatรวมภายนอกเป็นค่าเริ่มต้น pandas.pydata.org/pandas-docs/stable/reference/api/…
atif93

6

ในระดับสูง:

  • .concat()เพียงแค่ซ้อนหลาย ๆ ตัวDataFrameเข้าด้วยกันไม่ว่าจะเป็นแนวตั้งหรือเย็บตามแนวนอนหลังจากจัดแนวดัชนี
  • .merge()สอดคล้องแรกที่สองDataFrame'เลือกคอลัมน์ที่พบบ่อย (s) DataFrameหรือดัชนีแล้วหยิบคอลัมน์ที่เหลือจากแถวชิดของแต่ละ

โดยเฉพาะอย่างยิ่ง.concat():

  • เป็นฟังก์ชันแพนด้าระดับบน
  • รวมแพนด้าสองตัวขึ้นไปในDataFrame แนวตั้งหรือแนวนอน
  • จัดแนวเฉพาะบนดัชนีเมื่อรวมในแนวนอน
  • ข้อผิดพลาดเมื่อDataFrameมีดัชนีที่ซ้ำกัน
  • ค่าเริ่มต้นคือการรวมภายนอกด้วยตัวเลือกสำหรับการรวมภายใน

และ.merge():

  • มีทั้งฟังก์ชันแพนด้าระดับบนสุดและDataFrameเมธอด (ณ แพนด้า 1.0)
  • รวมสองอย่างในDataFrameแนวนอน
  • สอดคล้องเรียกDataFrame's คอลัมน์ (s) หรือดัชนีกับคนอื่น ๆ DataFrame' s คอลัมน์ (s) หรือดัชนี
  • จัดการค่าที่ซ้ำกันในคอลัมน์หรือดัชนีการรวมโดยการแสดงผลิตภัณฑ์คาร์ทีเซียน
  • ค่าเริ่มต้นคือการรวมภายในโดยมีตัวเลือกสำหรับซ้ายด้านนอกและด้านขวา

โปรดทราบว่าในการดำเนินการpd.merge(left, right)หากleftมีสองแถวที่มีค่าเดียวกันจากคอลัมน์หรือดัชนีการรวมแต่ละแถวจะรวมกับrightแถวที่สอดคล้องกันซึ่งส่งผลให้เกิดผลิตภัณฑ์คาร์ทีเซียน ในทางตรงกันข้ามถ้ามีการใช้ในการรวมคอลัมน์เราต้องให้แน่ใจว่าไม่มีซ้ำดัชนีที่มีอยู่ทั้งใน.concat()DataFrame

พูดจริง:

  • พิจารณา.concat()ครั้งแรกเมื่อรวมเป็นเนื้อเดียวกันDataFrameในขณะที่พิจารณาครั้งแรกเมื่อรวมที่สมบูรณ์.merge()DataFrame
  • .concat()หากจำเป็นที่จะต้องผสานแนวตั้งไปกับ หากจำเป็นต้องรวมแนวนอนผ่านคอลัมน์ให้ไปด้วย.merge()ซึ่งโดยค่าเริ่มต้นจะรวมกับคอลัมน์ที่เหมือนกัน

ข้อมูลอ้างอิง: Pandas 1.x Cookbook


2

ความแตกต่างที่สำคัญระหว่างการผสานและการเชื่อมต่อกันคือการผสานช่วยให้คุณสามารถ "รวม" ตารางที่มีโครงสร้างมากขึ้นโดยที่การใช้ concat กว้างกว่าและมีโครงสร้างน้อยกว่า

ผสาน

อ้างอิงเอกสาร , pd.DataFrame.mergeใช้เวลาที่เหมาะสมเป็นอาร์กิวเมนต์จำเป็นซึ่งคุณสามารถคิดว่ามันเป็นมาร่วมงานกับตารางด้านซ้ายและด้านขวาของตารางตามที่กำหนดไว้ล่วงหน้าโครงสร้างเข้าร่วมดำเนินงาน หมายเหตุ: ความคมชัดสำหรับพารามิเตอร์ที่เหมาะสม

พารามิเตอร์ที่จำเป็น

  • ขวา : DataFrame หรือชื่อ Series

พารามิเตอร์เสริม

  • อย่างไร : {'left', 'right', 'outer', 'inner'} default 'inner'
  • บน : ป้ายกำกับหรือรายการ
  • left_on : ป้ายกำกับหรือรายการหรือเหมือนอาร์เรย์
  • right_on : ป้ายกำกับหรือรายการหรือเหมือนอาร์เรย์
  • left_index : bool ค่าเริ่มต้น False
  • right_index : bool ค่าเริ่มต้น False
  • เรียงลำดับ : bool, default False
  • คำต่อท้าย : tuple ของ (str, str), ค่าเริ่มต้น ('_x', '_y')
  • copy : bool ค่าเริ่มต้น True
  • ตัวบ่งชี้ : บูลหรือ str, ค่าเริ่มต้น False
  • ตรวจสอบความถูกต้อง : str, ไม่บังคับ

สำคัญ: pd.DataFrame.mergeต้องการสิทธิ์ในการเป็นpd.DataFrameหรือตั้งชื่อpd.Seriesวัตถุ

เอาต์พุต

  • ผลตอบแทน : DataFrame

นอกจากนี้หากเราตรวจสอบ docstring สำหรับ Merge Operation บนแพนด้าอยู่ด้านล่าง:

ดำเนินการผสานฐานข้อมูล (SQL) ระหว่างออบเจ็กต์ DataFrame หรือ Series สองรายการโดยใช้คอลัมน์เป็นคีย์หรือดัชนีแถว

Concat

อ้างถึงเอกสารของpd.concatโน้ตแรกที่พารามิเตอร์ไม่มีชื่อใด ๆ ของตาราง data_frame ชุดเมทริกซ์ฯลฯ แต่objsแทน นั่นคือคุณสามารถส่ง "คอนเทนเนอร์ข้อมูล" จำนวนมากซึ่งกำหนดเป็น:

Iterable[FrameOrSeriesUnion], Mapping[Optional[Hashable], FrameOrSeriesUnion]

พารามิเตอร์ที่จำเป็น

  • objs : ลำดับหรือการแม็ปของวัตถุ Series หรือ DataFrame

พารามิเตอร์เสริม

  • แกน : {0 / 'ดัชนี', 1 / 'คอลัมน์'}, ค่าเริ่มต้น 0
  • เข้าร่วม : {'inner', 'outer'}, default 'outer'
  • Ignore_index : bool, default False
  • คีย์ : ลำดับค่าเริ่มต้นไม่มี
  • ระดับ : รายการลำดับเริ่มต้นไม่มี
  • ชื่อ : รายการค่าเริ่มต้นไม่มี
  • Verify_integrity : bool, default False
  • เรียงลำดับ : bool, default False
  • copy : bool ค่าเริ่มต้น True

เอาต์พุต

  • ผลตอบแทน : วัตถุประเภทของ objs

ตัวอย่าง

รหัส

import pandas as pd

v1 = pd.Series([1, 5, 9, 13])
v2 = pd.Series([10, 100, 1000, 10000])
v3 = pd.Series([0, 1, 2, 3])

df_left = pd.DataFrame({
    "v1": v1,
    "v2": v2,
    "v3": v3
    })
df_right = pd.DataFrame({
    "v4": [5, 5, 5, 5],
    "v5": [3, 2, 1, 0]
    })


df_concat = pd.concat([v1, v2, v3])

# Performing operations on default

merge_result = df_left.merge(df_right, left_index=True, right_index=True)
concat_result = pd.concat([df_left, df_right], sort=False)
print(merge_result)
print('='*20)
print(concat_result)

เอาต์พุตรหัส

   v1     v2  v3  v4  v5
0   1     10   0   5   3
1   5    100   1   5   2
2   9   1000   2   5   1
3  13  10000   3   5   0
====================
     v1       v2   v3   v4   v5
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0

อย่างไรก็ตามคุณสามารถบรรลุผลลัพธ์แรก (ผสาน) กับ concat ได้โดยการเปลี่ยนพารามิเตอร์แกน

concat_result = pd.concat([df_left, df_right], sort=False, axis=1)

สังเกตพฤติกรรมต่อไปนี้

concat_result = pd.concat([df_left, df_right, df_left, df_right], sort=False)

เอาต์พุต;

     v1       v2   v3   v4   v5
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0
3   NaN      NaN  NaN  5.0  0.0
0   1.0     10.0  0.0  NaN  NaN
1   5.0    100.0  1.0  NaN  NaN
2   9.0   1000.0  2.0  NaN  NaN
3  13.0  10000.0  3.0  NaN  NaN
0   NaN      NaN  NaN  5.0  3.0
1   NaN      NaN  NaN  5.0  2.0
2   NaN      NaN  NaN  5.0  1.0
3   NaN      NaN  NaN  5.0  0.0

ซึ่งคุณไม่สามารถดำเนินการที่คล้ายกันกับการผสานได้เนื่องจากอนุญาตให้ใช้ DataFrame เดียวหรือซีรี่ส์ที่มีชื่อเท่านั้น

merge_result = df_left.merge([df_right, df_left, df_right], left_index=True, right_index=True)

เอาต์พุต;

TypeError: Can only merge Series or DataFrame objects, a <class 'list'> was passed

สรุป

ดังที่คุณอาจสังเกตเห็นแล้วว่าอินพุตและเอาต์พุตอาจแตกต่างกันระหว่าง "merge" และ "concat"

ดังที่ฉันได้กล่าวไว้ในตอนต้นความแตกต่าง (หลัก) ประการแรกคือการ "ผสาน" ทำการรวมที่มีโครงสร้างมากขึ้นกับชุดของวัตถุและพารามิเตอร์ที่ จำกัด โดยที่ "concat" ทำการรวมที่เข้มงวดน้อยกว่า / กว้างกว่ากับชุดที่กว้างกว่า ของวัตถุและพารามิเตอร์

สรุปแล้วการผสานมีความทนทานต่อการเปลี่ยนแปลงน้อยกว่า / (อินพุต) และ "concat" มีความไวต่อการเปลี่ยนแปลงน้อยกว่า / (อินพุต) คุณสามารถ "ผสาน" ได้โดยใช้ "concat" แต่สิ่งที่ตรงกันข้ามไม่ได้เป็นจริงเสมอไป

การดำเนินการ "ผสาน" ใช้คอลัมน์ Data Frame (หรือชื่อของpd.Seriesวัตถุ) หรือดัชนีแถวและเนื่องจากจะใช้เอนทิตีเหล่านั้นเท่านั้นจึงทำการผสานในแนวนอนของ Data Frames หรือ Series และไม่ได้ใช้การดำเนินการแนวตั้งเป็นผลลัพธ์

หากคุณต้องการดูเพิ่มเติมคุณสามารถเจาะลึกซอร์สโค้ดได้เล็กน้อย

  • ซอร์สโค้ดสำหรับconcat
  • ซอร์สโค้ดสำหรับการผสาน

0

ฟังก์ชัน concat เท่านั้นที่มีพารามิเตอร์แกน Merge ใช้เพื่อรวมดาต้าเฟรมแบบเคียงข้างกันตามค่าในคอลัมน์ที่แชร์ดังนั้นจึงไม่จำเป็นต้องใช้พารามิเตอร์แกน


-2

โดยค่าเริ่มต้น:
join เป็นคอลัมน์ที่ชาญฉลาดการเข้าร่วม
pd.merge เป็นคอลัมน์ที่ชาญฉลาดในการเข้าร่วม
pd.concat เป็นการรวมแถวนอก

pd.concat:
รับอาร์กิวเมนต์ Iterable ดังนั้นจึงไม่สามารถใช้ DataFrames ได้โดยตรง (ใช้ [df, df2])
ขนาดของ DataFrame ควรตรงตามแกน

เข้าร่วมและ pd.merge:
สามารถใช้อาร์กิวเมนต์ DataFrame

คลิกเพื่อดูภาพเพื่อทำความเข้าใจว่าทำไมโค้ดด้านล่างถึงทำสิ่งเดียวกัน

df1.join(df2)
pd.merge(df1, df2, left_index=True, right_index=True)
pd.concat([df1, df2], axis=1)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.