Різниця (и) між merge () та concat () у пандах


85

Яка суттєва різниця (и) між pd.DataFrame.merge()і pd.concat()?

Поки що це я знайшов, будь ласка, прокоментуйте, наскільки повним і точним є моє розуміння:

  • .merge()може використовувати лише стовпці (плюс індекси рядків), і це семантично підходить для операцій у стилі бази даних. .concat()може використовуватися з будь-якою віссю, використовуючи лише індекси, і дає можливість додавання ієрархічного індексу.

  • До речі, це допускає таку надмірність: обидва можуть поєднувати два кадри даних, використовуючи індекси рядків.

  • pd.DataFrame.join() просто пропонує скорочення для підмножини випадків використання .merge()

(Pandas чудово розглядає дуже широкий спектр випадків використання при аналізі даних. Це може бути трохи страшним вивченням документації, щоб з’ясувати, який найкращий спосіб виконати певне завдання.)


3
Також, пов'язані: stackoverflow.com/a/37891437/1972495 обговорення навколо .merge()та .join().
WindChimes

2
На об'єднанні, приєднанні та об'єднанні, я вважаю, що ця відповідь є дуже чіткою щодо того, як всі вони можуть бути використані для виконання одних і тих же дій (вони, здається, є просто альтернативним інтерфейсом для однакової функціональності). Завдяки вашому питанню (і відповіді, яку ви посилаєте в коментарі), я знаю, нарешті, розумію, як пов’язані об’єднання та приєднання. Мені досі незрозуміло, використовує concat іншу реалізацію чи ні (мабуть, мені доведеться подивитися на вихідний код ...)
pietroppeter

Відповіді:


77

Дуже висока різниця в рівні полягає в тому, що merge()використовується для об'єднання двох (або більше) кадрів даних на основі значень загальних стовпців (також можуть використовуватися індекси, використання left_index=Trueта / або right_index=True), і concat()використовується для додавання одного (або більше) кадрів даних один під іншим (або вбік, залежно від того, встановлено axisпараметр 0 або 1).

join()використовується для об'єднання 2 кадрів даних на основі індексу; замість використання 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.

Тоді як join можна використовувати для об’єднання двох DataFrames з різними індексами.


7
Мені подобається ця відповідь, оскільки в ній зазначено, що розміри повинні збігатися при об'єднанні. concatце не що інше, як приклеювання кількох кадрів даних поверх / поруч один з одним. Він не знає вмісту в тому сенсі, що він просто двічі відображатиме один і той же стовпець. Тоді mergeяк фактично буде об’єднано стовпці, коли вони однакові.
jorijnsmit

2
Я думаю, що це неправда. Навіть відповідь вище (@Abhishek Sawant) наводить приклад, concatколи розміри не збігаються.
michcio1234

7

Зараз я намагаюся зрозуміти суттєву різницю між 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

5

На високому рівні:

  • .concat()просто складає по кілька, DataFrameвертикально або горизонтально, після вирівнювання за індексом
  • .merge()спочатку вирівнює дві DataFrameобрані загальні стовпці (колонки) або індекс, а потім підбирає решту стовпців із вирівняних рядків кожного DataFrame.

Більш конкретно .concat():

  • Це функція панди верхнього рівня
  • Поєднує дві або більше панд DataFrame вертикально або горизонтально
  • Вирівнюється лише за покажчиком при горизонтальному поєднанні
  • Помилки, коли будь-який із DataFrameмістить дублікат індексу.
  • За замовчуванням зовнішнє з'єднання з можливістю внутрішнього з'єднання

І .merge():

  • Існує як функція панд верхнього рівня, так і як DataFrameметод (станом на панд 1.0)
  • Поєднує рівно дві DataFrameгоризонталі
  • Вирівнює викликає DataFrame«ов шпальти (ів) або індекс з іншого DataFrame» колонки з (ами) або індексом
  • Обробляє повторювані значення на стовпцях, що з’єднуються, або індексі , виконуючи декартовий твір
  • За замовчуванням внутрішнє з'єднання з параметрами лівого, зовнішнього та правого

Зверніть увагу, що при виконанні pd.merge(left, right), якщо leftє два рядки, що містять однакові значення з об'єднуючих стовпців або індексу, кожен рядок буде поєднуватися з rightвідповідними рядками, що приводить до декартового продукту. З іншого боку, якщо .concat()використовується для об'єднання стовпців, нам потрібно переконатися, що в жодному з них не існує дубльованого індексу DataFrame.

Практично кажучи:

  • Розглянемо .concat()перший при комбінуванні однорідна DataFrame, а розглянемо .merge()перший, комбінуючи комплементарної DataFrame.
  • Якщо потрібно об’єднати вертикально, перейдіть до .concat(). Якщо потрібно об’єднати горизонтально через стовпці, перейдіть за допомогою .merge(), який за замовчуванням об’єднує загальні стовпці.

Довідково: Кулінарна книга Pandas 1.x


2

Основна відмінність між злиттям і конкатом полягає в тому, що злиття дозволяє виконувати більш структуроване "об'єднання" таблиць, де використання конката ширше і менш структуровано.

Злиття

Посилаючись на документацію , pd.DataFrame.mergeприймає право як необхідний аргумент, що можна вважати об’єднанням лівої таблиці та правої таблиці згідно з деякою заздалегідь визначеною структурованою операцією об’єднання. Зверніть увагу на визначення правого параметра .

Обов’язкові параметри

  • праворуч : DataFrame або названа серія

Необов’язкові параметри

  • як : {'лівий', 'правий', 'зовнішній', 'внутрішній'} за замовчуванням 'внутрішній'
  • на : ярлик або список
  • left_on : мітка або список або схожий на масив
  • right_on : мітка або список або схожий на масив
  • left_index : bool, за замовчуванням False
  • right_index : bool, за замовчуванням False
  • сортувати : bool, за замовчуванням False
  • суфікси : кортеж (str, str), за замовчуванням ('_x', '_y')
  • copy : bool, за замовчуванням True
  • індикатор : bool або str, за замовчуванням False
  • перевірити : str, необов’язково

Важливо: pd.DataFrame.merge вимагає права бути об’єктом pd.DataFrameабо іменованим pd.Series.

Вихідні дані

  • Повертає : DataFrame

Крім того, якщо ми перевіримо документацію для операції злиття на пандах:

Виконайте операцію злиття бази даних (SQL) між двома об'єктами DataFrame або Series, використовуючи або стовпці як ключі, або їх індекси рядків

Конкат

Зверніться до документації по pd.concat, першої нота , що параметр не названий будь-який з таблиці, data_frame, серії, матриця і т.д., але Objs замість цього. Тобто ви можете передати багато "контейнерів даних", які визначаються як:

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

Обов’язкові параметри

  • objs : послідовність або відображення об’єктів Series або DataFrame

Необов’язкові параметри

  • вісь : {0 / 'індекс', 1 / 'стовпці'}, за замовчуванням 0
  • join : {'внутрішній', 'зовнішній'}, за замовчуванням 'зовнішній'
  • ignore_index : bool, за замовчуванням False
  • клавіші : послідовність, за замовчуванням Немає
  • рівні : список послідовностей, за замовчуванням Немає
  • імена : список, за замовчуванням Немає
  • verify_integrity : bool, за замовчуванням False
  • сортувати : bool, за замовчуванням 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

Висновок

Як ви вже помічали, вхідні та вихідні дані можуть відрізнятися між "злиттям" та "конкатом".

Як я вже згадував на початку, найперша (основна) відмінність полягає в тому, що "злиття" виконує більш структуроване об'єднання з набором обмеженого набору об'єктів і параметрів, де як "concat" виконує менш жорстке / ширше об'єднання з ширшим набором об'єктів і параметрів.

Загалом, злиття менш толерантне до змін / (введення), а «concat» - більш вільне / менш чутливе до змін / (введення). Ви можете досягти "злиття", використовуючи "concat", але зворотне не завжди справедливо.

Операція "Злиття" використовує стовпці фреймів даних (або ім'я pd.Seriesоб'єкта) або індекси рядків, і оскільки вона використовує лише ці сутності, вона виконує горизонтальне об'єднання кадрів даних або рядів, і в результаті не застосовує вертикальну операцію.

Якщо ви хочете побачити більше, ви можете трохи поринути у вихідний код;


-2

за замовчуванням:
join - це ліве об’єднання
в стовпці
pd.merge - внутрішнє об’єднання в стовпці pd.concat - зовнішнє об’єднання в рядку

pd.concat:
бере аргументи, що піддаються ітерації. Таким чином, він не може приймати DataFrames безпосередньо (використовуйте [df, df2])
Розміри DataFrame повинні збігатися вздовж осі

Join і pd.merge:
може приймати аргументи DataFrame

Клацніть, щоб побачити зображення, щоб зрозуміти, чому код нижче робить те саме

df1.join(df2)
pd.merge(df1, df2, left_index=True, right_index=True)
pd.concat([df1, df2], axis=1)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.