Как объединить dataframe pandas
Перейти к содержимому

Как объединить dataframe pandas

  • автор:

Как объединить Pandas DataFrames в несколько столбцов

Часто вы можете захотеть объединить два кадра данных pandas в нескольких столбцах. К счастью, это легко сделать с помощью функции pandas merge() , которая использует следующий синтаксис:

pd.merge(df1, df2, left_on=['col1','col2'], right_on = ['col1','col2']) 

В этом руководстве объясняется, как использовать эту функцию на практике.

Пример 1: объединение нескольких столбцов с разными именами

Предположим, у нас есть следующие два Pandas DataFrames:

import pandas as pd #create and view first DataFrame df1 = pd.DataFrame() print(df1) a1 b c 0 0 0 11 1 0 0 8 2 1 1 10 3 1 1 6 4 2 1 6 #create and view second DataFrame df2 = pd.DataFrame() print(df2) a2 b d 0 0 0 22 1 1 0 24 2 1 0 25 3 1 1 33 4 3 1 37 

В следующем коде показано, как выполнить левое соединение с использованием нескольких столбцов из обоих фреймов данных:

pd.merge(df1, df2, how='left', left_on=['a1', 'b'], right_on = ['a2',' b']) a1 b c a2 d 0 0 0 11 0.0 22.0 1 0 0 8 0.0 22.0 2 1 1 10 1.0 33.0 3 1 1 6 1.0 33.0 4 2 1 6 NaN NaN 

Пример 2: объединение нескольких столбцов с одинаковыми именами

Предположим, у нас есть следующие два кадра данных pandas с одинаковыми именами столбцов:

import pandas as pd #create DataFrames df1 = pd.DataFrame() df2 = pd.DataFrame() 

В этом случае мы можем упростить использование on = [‘a’, ‘b’], поскольку имена столбцов одинаковы в обоих DataFrames:

pd.merge(df1, df2, how='left', on=['a', 'b']) a b c d 0 0 0 11 22.0 1 0 0 8 22.0 2 1 1 10 33.0 3 1 1 6 33.0 4 2 1 6 NaN 

Как объединить dataframe pandas

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

Изменение формы и объединение таблиц — Python: Pandas

В работе с данными приходится собирать их из разных источников и объединять в единую структуру. В библиотеке Pandas реализован функционал для таких операций над табличными данными в виде методов:

На данном уроке рассмотрим практические случаи, в которых они применяются.

Метод concat()

За основу возьмем данные о кликах на сайтах 4 магазинов за 28 дней.

df_clicks = pd.read_csv('./data/Cite_clicks.csv', index_col=0) print(df_clicks.head()) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 319.0 328.0 # 2 292.0 274.0 292.0 301.0 # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 

Разобьем исходные данные на два датафрейма за первую и вторую недели месяца. Это операция делается с использованием срезов.

df_clicks_first_week = df_clicks[:7] df_clicks_second_week = df_clicks[7:14] print(df_clicks_first_week) print(df_clicks_second_week) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 319.0 328.0 # 2 292.0 274.0 292.0 301.0 # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 445.0 418.0 409.0 445.0 # 7 481.0 400.0 481.0 409.0 # # SHOP1 SHOP2 SHOP3 SHOP4 # day # 8 NaN 267.0 333.0 344.0 # 9 300.0 278.0 300.0 311.0 # 10 289.0 311.0 -278.0 289.0 # 11 344.0 388.0 344.0 333.0 # 12 421.0 377.0 399.0 355.0 # 13 487.0 454.0 -443.0 487.0 # 14 531.0 432.0 531.0 443.0 

Операция, обратная разбиению — конкатенация, применяется, чтобы собрать куски данных в единый фрагмент. Если предположить, что отчетные материалы за разные недели лежат в разных таблицах, а для аналитика необходимо поработать над всеми значениями сразу, то можно использовать метод concat() . В качестве параметров ему передается список тех датасетов, которые необходимо объединить:

df_weeks_concat = pd.concat([ df_clicks_first_week, df_clicks_second_week ]) print(df_weeks_concat) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 319.0 328.0 # 2 292.0 274.0 292.0 301.0 # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 445.0 418.0 409.0 445.0 # 7 481.0 400.0 481.0 409.0 # 8 NaN 267.0 333.0 344.0 # 9 300.0 278.0 300.0 311.0 # 10 289.0 311.0 -278.0 289.0 # 11 344.0 388.0 344.0 333.0 # 12 421.0 377.0 399.0 355.0 # 13 487.0 454.0 -443.0 487.0 # 14 531.0 432.0 531.0 443.0 

Рассмотрим ситуацию, в которой данные разбиты по парам магазинов. Возможно, это данные из разных городов, и лежат они в разных таблицах баз данных:

df_clicks_two_first = df_clicks[['SHOP1', 'SHOP2']] df_clicks_two_last = df_clicks[['SHOP3', 'SHOP4']] print(df_clicks_two_first.head()) print(df_clicks_two_last.head()) # => SHOP1 SHOP2 # day # 1 319.0 -265.0 # 2 292.0 274.0 # 3 283.0 301.0 # 4 328.0 364.0 # 5 391.0 355.0 # # SHOP3 SHOP4 # day # 1 319.0 328.0 # 2 292.0 301.0 # 3 274.0 283.0 # 4 328.0 NaN # 5 373.0 337.0 

Чтобы собрать их в единое целое, применяется метод concat() , но указывается направление объединения с помощью параметра axis :

  • 0 — объединение происходит по строкам
  • 1 — по столбцам
df_shop_concat = pd.concat([ df_clicks_two_first, df_clicks_two_last ], axis=1) print(df_shop_concat.head()) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 319.0 328.0 # 2 292.0 274.0 292.0 301.0 # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 

Стоит быть внимательными с направлением объединения. Если его не указать в данном примере, то результат будет не тот, который ожидается:

print(pd.concat([ df_clicks_two_first, df_clicks_two_last ])) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 NaN NaN # 2 292.0 274.0 NaN NaN # 3 283.0 301.0 NaN NaN # 4 328.0 364.0 NaN NaN # 5 391.0 355.0 NaN NaN 

Фрагменты данных на подобии срезов по неделям и парам магазинов довольно типичная ситуация. Однако бывают случаи, когда срезы делаются по разным пересекающимся промежуткам времени. Рассмотрим данные кликов для пар магазинов за пять рабочих дней:

df_clicks_two_first = df_clicks[['SHOP1', 'SHOP2']][:5] df_clicks_two_last = df_clicks[['SHOP3', 'SHOP4']][2:7] print(df_clicks_two_first) print(df_clicks_two_last) # => SHOP1 SHOP2 # day # 1 319.0 -265.0 # 2 292.0 274.0 # 3 283.0 301.0 # 4 328.0 364.0 # 5 391.0 355.0 # # SHOP3 SHOP4 # day # 3 274.0 283.0 # 4 328.0 NaN # 5 373.0 337.0 # 6 409.0 445.0 # 7 481.0 409.0 

Здесь дни месяца не совпадают, но пересекаются. Для объединения также используется метод concat() , который объединит по соответствующим индексам и оставит пропуски в тех днях, для которых значений нет.

df_concat = pd.concat([ df_clicks_two_first, df_clicks_two_last ],axis=1) print(df_concat) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 NaN NaN # 2 292.0 274.0 NaN NaN # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 NaN NaN 409.0 445.0 # 7 NaN NaN 481.0 409.0 

Метод join()

Метод concat() позволяет производить операции конкатенации по направлениям. Однако при работе с данными требуются более сложные объединения данных. Одним из методов, который поддерживает различные сценарии объединения данных по индексам, является метод join() :

df_join_to_first = df_clicks_two_first.join( df_clicks_two_last ) print(df_join_to_first) # => SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 NaN NaN # 2 292.0 274.0 NaN NaN # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 

Важно отметить, что join() не является методом Pandas, а применяется к датафрейму. Также важно, к какому датафрейму при объединении он применяется. Если поменять местами датафреймы в примере выше, то результат будет отличаться:

df_join_to_last = df_clicks_two_last.join( df_clicks_two_first ) print(df_join_to_last) # => SHOP3 SHOP4 SHOP1 SHOP2 # day # 3 274.0 283.0 283.0 301.0 # 4 328.0 NaN 328.0 364.0 # 5 373.0 337.0 391.0 355.0 # 6 409.0 445.0 NaN NaN # 7 481.0 409.0 NaN NaN 

В примерах выше в результирующем датафрейме присутствуют только индексы датафрейма, к которому применялся данный метод. Такой способ объединения называется left join и применяется по умолчанию. Метод join() поддерживает различные сценарии объединения и включает такие случаи:

  • inner join — объединение по пересечению индексов
  • right join — внешнее объединение по всем индексам объединяемых датафреймов

Для их использования в примерах ниже указываются соответствующие значения параметра how :

print('left join:') print(df_clicks_two_first.join( df_clicks_two_last, how='left' )) print('right join:') print(df_clicks_two_first.join( df_clicks_two_last, how='right' )) print('inner join:') print(df_clicks_two_first.join( df_clicks_two_last, how='inner' )) print('outer join:') print(df_clicks_two_first.join( df_clicks_two_last, how='outer' )) # => left join: # SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 NaN NaN # 2 292.0 274.0 NaN NaN # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # # right join: # SHOP1 SHOP2 SHOP3 SHOP4 # day # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 NaN NaN 409.0 445.0 # 7 NaN NaN 481.0 409.0 # # inner join: # SHOP1 SHOP2 SHOP3 SHOP4 # day # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # # outer join: # SHOP1 SHOP2 SHOP3 SHOP4 # day # 1 319.0 -265.0 NaN NaN # 2 292.0 274.0 NaN NaN # 3 283.0 301.0 274.0 283.0 # 4 328.0 364.0 328.0 NaN # 5 391.0 355.0 373.0 337.0 # 6 NaN NaN 409.0 445.0 # 7 NaN NaN 481.0 409.0 

Метод merge()

Объединение данных можно производить не только по индексам, но и по столбцам значений двух датафреймов. Для этого не достаточно функционала метода join() , который может производить объединения по индексам датафреймов. Для таких случаев в Pandas используется метод merge() .

Рассмотрим датасет с кликами, в котором дни месяца указаны в столбце day , а не в индексе строк:

df_clicks = df_clicks.reset_index() print(df_clicks.head()) # => day SHOP1 SHOP2 SHOP3 SHOP4 # 0 1 319.0 -265.0 319.0 328.0 # 1 2 292.0 274.0 292.0 301.0 # 2 3 283.0 301.0 274.0 283.0 # 3 4 328.0 364.0 328.0 NaN # 4 5 391.0 355.0 373.0 337.0 

Будем решать задачу по объединению двух датасетов, содержащих пятидневные срезы по парам магазинов:

df_clicks_two_first = df_clicks[['day', 'SHOP1', 'SHOP2']][:5] df_clicks_two_last = df_clicks[['day', 'SHOP3', 'SHOP4']][2:7] print(df_clicks_two_first) print(df_clicks_two_last) # => day SHOP1 SHOP2 # 0 1 319.0 -265.0 # 1 2 292.0 274.0 # 2 3 283.0 301.0 # 3 4 328.0 364.0 # 4 5 391.0 355.0 # # day SHOP3 SHOP4 # 2 3 274.0 283.0 # 3 4 328.0 NaN # 4 5 373.0 337.0 # 5 6 409.0 445.0 # 6 7 481.0 409.0 

Для их объединения необходимо указать сперва левый, а затем правый датафреймы. Также нужно определить по каким столбцам в каждом из датафреймов будет происходить объединение.

df_merged = pd.merge( df_clicks_two_first, df_clicks_two_last, left_on='day', right_on='day' ) print(df_merged) # => day SHOP1 SHOP2 SHOP3 SHOP4 # 0 3 283.0 301.0 274.0 283.0 # 1 4 328.0 364.0 328.0 NaN # 2 5 391.0 355.0 373.0 337.0 

Также как и в методе join() в методе merge() поддерживаются различные сценарии объединения данных:

print('inner merge:') print(pd.merge( df_clicks_two_first, df_clicks_two_last, left_on='day', right_on='day', how='inner' )) print('left merge:') print(pd.merge( df_clicks_two_first, df_clicks_two_last, left_on='day', right_on='day', how='left' )) print('right merge:') print(pd.merge( df_clicks_two_first, df_clicks_two_last, left_on='day', right_on='day', how='right' )) print('outer merge:') print(pd.merge( df_clicks_two_first, df_clicks_two_last, left_on='day', right_on='day', how='outer' )) # => inner merge: # day SHOP1 SHOP2 SHOP3 SHOP4 # 0 3 283.0 301.0 274.0 283.0 # 1 4 328.0 364.0 328.0 NaN # 2 5 391.0 355.0 373.0 337.0 # # left merge: # day SHOP1 SHOP2 SHOP3 SHOP4 # 0 1 319.0 -265.0 NaN NaN # 1 2 292.0 274.0 NaN NaN # 2 3 283.0 301.0 274.0 283.0 # 3 4 328.0 364.0 328.0 NaN # 4 5 391.0 355.0 373.0 337.0 # # right merge: # day SHOP1 SHOP2 SHOP3 SHOP4 # 0 3 283.0 301.0 274.0 283.0 # 1 4 328.0 364.0 328.0 NaN # 2 5 391.0 355.0 373.0 337.0 # 3 6 NaN NaN 409.0 445.0 # 4 7 NaN NaN 481.0 409.0 # # outer merge: # day SHOP1 SHOP2 SHOP3 SHOP4 # 0 1 319.0 -265.0 NaN NaN # 1 2 292.0 274.0 NaN NaN # 2 3 283.0 301.0 274.0 283.0 # 3 4 328.0 364.0 328.0 NaN # 4 5 391.0 355.0 373.0 337.0 # 5 6 NaN NaN 409.0 445.0 # 6 7 NaN NaN 481.0 409.0 

Выводы

На данном уроке мы познакомились с различными методами Pandas для объединения табличных данных. Рассмотренные методы применяются по мере усложнения производимой операции:

  • concat() — данные объединяются по строкам или по столбцам с сохранением всех значений
  • join() — объединяюся датафреймы по индексам

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Как объединить 4 DataFrame в один?

Необходимо соединить df3 c остальными df . При этом необходимо соединить df4 с помощью left join , а с оставшимися df — через inner (реальные данные содержат более 100 000 рядов).

pd.concat([df3, df4], axis=0, join = 'left').concat([df3, df1, df2], axis=0, join = 'inner') 

выдаёт ValueError. Подскажите, пожалуйста, эффективный способ решения данной задачи?
Отслеживать
12.5k 7 7 золотых знаков 19 19 серебряных знаков 48 48 бронзовых знаков
задан 26 мая 2021 в 14:12
21 3 3 бронзовых знака

а зачем вы конкатенируете все цепочкой, особенно, если не до конца понимаете, как этом метод работает? вы же сами себе алгоритм расписали. так и делайте, сначала одно, а потом другое.

26 мая 2021 в 14:32

А по какой колонке то вы join делаете, по индексу? То есть фактически не join , а именно concat просто нужен в данном случае (индекс у них у всех одинаковый)?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *