Слияние панд 101

  • Как я могу выполнить (INNER | (LEFT | RIGHT | FULL) OUTER) JOIN с пандами?
  • Как добавить NaN для недостающих строк после слияния?
  • Как мне избавиться от NaN после слияния?
  • Могу я слить по индексу?
  • Как мне объединить несколько DataFrames?
  • Перекрестное соединение с пандами
  • merge? join? concat? update? ВОЗ? Какие? Почему?!

... и больше. Я видел эти повторяющиеся вопросы о различных аспектах функциональности слияния панд. Большая часть информации о слиянии и различных вариантах его использования сегодня фрагментирована между десятками плохо сформулированных, не поддающихся поиску сообщений. Цель здесь - сопоставить некоторые из наиболее важных моментов для потомков.

Эти вопросы и ответы должны стать следующей частью серии полезных руководств пользователя по распространенным идиомам pandas (см. этот пост о повороте и этот пост о конкатенации, которых я коснусь позже).

Обратите внимание, что это сообщение нет, предназначенное для замены документация, так что прочтите и его! Некоторые примеры взяты оттуда.


Оглавление

For ease of access.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
686
0
242 656
5

Ответы 5

Дополнительный визуальный вид pd.concat([df0, df1], kwargs). Обратите внимание, что значение kwarg axis=0 или axis=1 не так интуитивно понятно, как df.mean() или df.apply(func).


on pd.concat([df0, df1])

Это красивая диаграмма. Могу я спросить, как вы это сделали?

cs95 20.05.2019 19:27

Встроенный документ Google "insert ==> drawing ... ==> new" (по состоянию на май 2019 г.). Но для ясности: единственная причина, по которой я использовал документ Google для этого изображения, заключается в том, что мои заметки хранятся в документе Google, и мне хотелось бы, чтобы изображение можно было быстро изменить в самом документе Google. На самом деле, теперь вы упомянули об этом, инструмент для рисования в Google doc довольно изящный.

eliu 21.05.2019 20:19

Вау, это здорово. Исходя из мира SQL, «вертикальное» соединение - это не соединение в моей голове, поскольку структура таблицы всегда фиксирована. Теперь даже подумайте, что пандам следует объединить concat и merge с параметром направления horizontal или vertical.

Ufos 01.08.2019 13:16

@Ufos Разве это не axis=1 и axis=0?

cs95 06.08.2019 19:31

да, теперь есть merge и concat, оси и все такое. Однако, как показывает @eliu, это все та же концепция слить с «левым», «правым» и «горизонтальным» или «вертикальным». Мне лично приходится заглядывать в документацию каждый раз, когда мне нужно вспомнить, какая «ось» - это 0, а какая - 1.

Ufos 19.08.2019 11:32

если возможно, кто-то должен обратиться к axis=0 и axis=1 в .mean() .apply() .dropna() .concat(). Мне нужно много думать, чтобы принимать решения по каждому случаю.

eliu 21.08.2019 23:08

В этом ответе я рассмотрю практические примеры.

Первый - pandas.concat.

Второй - слияние фреймов данных из индекса одного и столбца другого.


1. pandas.concat

Учитывая следующий DataFrames с такими же именами столбцов:

Preco2018 с размером (8784, 5)

DataFrame 1

Preco 2019 с размером (8760, 5)

DataFrame 2

У них такие же имена столбцов.

Вы можете комбинировать их, используя pandas.concat, просто

import pandas as pd

frames = [Preco2018, Preco2019]

df_merged = pd.concat(frames)

В результате получается DataFrame следующего размера (17544, 5)

DataFrame result of the combination of two dataframes

Если вы хотите визуализировать, он работает так

How concat works

(Источник)


2. Слияние по столбцу и индексу

В этой части я рассмотрю конкретный случай: если нужно объединить индекс одного фрейма данных и столбец другого фрейма данных.

Допустим, у вас есть фрейм данных Geo с 54 столбцами, один из которых является Date Data, который имеет тип datetime64[ns].

И фрейм данных Price, в котором есть один столбец с ценой и индексом, соответствует датам

В этом конкретном случае для их объединения используется pd.merge

merged = pd.merge(Price, Geo, left_index=True, right_on='Data')

В результате получается следующий фрейм данных

В этом посте будут рассмотрены следующие темы:

  • как правильно обобщить на несколько DataFrames (и почему у merge здесь недостатки)
  • объединение уникальных ключей
  • слияние на неуникальных ключах

BACK TO TOP



Обобщение на несколько фреймов данных

Часто возникает ситуация, когда необходимо объединить несколько DataFrames. Наивно, это можно сделать, объединив вызовы merge:

df1.merge(df2, ...).merge(df3, ...)

Однако для многих DataFrames это быстро выходит из-под контроля. Кроме того, может потребоваться обобщение для неизвестного количества DataFrames.

Здесь я представляю pd.concat для многосторонних соединений по ключам уникальный и DataFrame.join для многосторонних соединений по ключам неуникальный. Во-первых, настройка.

# Setup.
np.random.seed(0)
A = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'valueA': np.random.randn(4)})    
B = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'valueB': np.random.randn(4)})
C = pd.DataFrame({'key': ['D', 'E', 'J', 'C'], 'valueC': np.ones(4)})
dfs = [A, B, C] 

# Note, the "key" column values are unique, so the index is unique.
A2 = A.set_index('key')
B2 = B.set_index('key')
C2 = C.set_index('key')

dfs2 = [A2, B2, C2]

Многостороннее слияние уникальных ключей

Если ваши ключи (здесь ключ может быть либо столбцом, либо индексом) уникальны, вы можете использовать pd.concat. Обратите внимание, что pd.concat присоединяется к DataFrames в индексе.

# merge on `key` column, you'll need to set the index before concatenating
pd.concat([
    df.set_index('key') for df in dfs], axis=1, join='inner'
).reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# merge on `key` index
pd.concat(dfs2, axis=1, sort=False, join='inner')

       valueA    valueB  valueC
key                            
D    2.240893 -0.977278     1.0

Опустите join='inner' для ПОЛНОГО ВНЕШНЕГО СОЕДИНЕНИЯ. Обратите внимание, что вы не можете указать соединения LEFT или RIGHT OUTER (если они вам нужны, используйте join, описанный ниже).


Многостороннее слияние ключей с дубликатами

concat работает быстро, но имеет свои недостатки. Он не может обрабатывать дубликаты.

A3 = pd.DataFrame({'key': ['A', 'B', 'C', 'D', 'D'], 'valueA': np.random.randn(5)})
pd.concat([df.set_index('key') for df in [A3, B, C]], axis=1, join='inner')
ValueError: Shape of passed values is (3, 4), indices imply (3, 2)

В этой ситуации мы можем использовать join, поскольку он может обрабатывать неуникальные ключи (обратите внимание, что join присоединяется к DataFrames по их индексу; он вызывает merge под капотом и выполняет LEFT OUTER JOIN, если не указано иное).

# join on `key` column, set as the index first
# For inner join. For left join, omit the "how" argument.
A.set_index('key').join(
    [df.set_index('key') for df in (B, C)], how='inner').reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# join on `key` index
A3.set_index('key').join([B2, C2], how='inner')

       valueA    valueB  valueC
key                            
D    1.454274 -0.977278     1.0
D    0.761038 -0.977278     1.0


Продолжить чтение

Перейдите к другим темам в Pandas Merging 101, чтобы продолжить обучение:

* you are here

В этом посте будут рассмотрены следующие темы:

  • Слияние с индексом при разных условиях
    • варианты для индексных объединений: merge, join, concat
    • слияние по индексам
    • слияние по индексу одного, столбцу другого
  • эффективное использование именованных индексов для упрощения синтаксиса слияния

BACK TO TOP



Соединения на основе индекса

TL; DR

There are a few options, some simpler than others depending on the use case.

  1. DataFrame.merge with left_index and right_index (or left_on and right_on using names indexes)
    • supports inner/left/right/full
    • can only join two at a time
    • supports column-column, index-column, index-index joins
  2. DataFrame.join (join on index)
    • supports inner/left (default)/right/full
    • can join multiple DataFrames at a time
    • supports index-index joins
  3. pd.concat (joins on index)
    • supports inner/full (default)
    • can join multiple DataFrames at a time
    • supports index-index joins

Индекс для индексных объединений

Настройка и основы

import pandas as pd
import numpy as np

np.random.seed([3, 14])
left = pd.DataFrame(data = {'value': np.random.randn(4)}, 
                    index=['A', 'B', 'C', 'D'])    
right = pd.DataFrame(data = {'value': np.random.randn(4)},  
                     index=['B', 'D', 'E', 'F'])
left.index.name = right.index.name = 'idxkey'

left
           value
idxkey          
A      -0.602923
B      -0.402655
C       0.302329
D      -0.524349

right
 
           value
idxkey          
B       0.543843
D       0.013135
E      -0.326498
F       1.385076

Обычно внутреннее соединение по индексу выглядит так:

left.merge(right, left_index=True, right_index=True)

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

Другие объединения следуют аналогичному синтаксису.

Известные альтернативы

  1. DataFrame.join по умолчанию - соединения по индексу. DataFrame.join по умолчанию выполняет ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ, поэтому здесь необходим how='inner'.

     left.join(right, how='inner', lsuffix='_x', rsuffix='_y')
    
              value_x   value_y
     idxkey                    
     B      -0.402655  0.543843
     D      -0.524349  0.013135
    

    Обратите внимание, что мне нужно было указать аргументы lsuffix и rsuffix, поскольку в противном случае join выдает ошибку:

     left.join(right)
     ValueError: columns overlap but no suffix specified: Index(['value'], dtype='object')
    

    Так как названия столбцов совпадают. Это не было бы проблемой, если бы они были названы по-другому.

     left.rename(columns = {'value':'leftvalue'}).join(right, how='inner')
    
             leftvalue     value
     idxkey                     
     B       -0.402655  0.543843
     D       -0.524349  0.013135
    
  2. pd.concat присоединяется к индексу и может присоединяться к двум или более DataFrames одновременно. По умолчанию он выполняет полное внешнее соединение, поэтому здесь требуется how='inner'.

     pd.concat([left, right], axis=1, sort=False, join='inner')
    
                value     value
     idxkey                    
     B      -0.402655  0.543843
     D      -0.524349  0.013135
    

    Для получения дополнительной информации о concat см. эта почта.


Индекс к объединению столбца

Чтобы выполнить внутреннее соединение с использованием индекса слева, столбец справа, вы будете использовать DataFrame.merge, комбинацию left_index=True и right_on=....

right2 = right.reset_index().rename({'idxkey' : 'colkey'}, axis=1)
right2
 
  colkey     value
0      B  0.543843
1      D  0.013135
2      E -0.326498
3      F  1.385076

left.merge(right2, left_index=True, right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135

Другие объединения следуют аналогичной структуре. Обратите внимание, что только merge может выполнять объединение индекса в столбец. Вы можете объединить несколько столбцов при условии, что количество уровней индекса слева равно количеству столбцов справа.

join и concat не способны к смешанному слиянию. Вам нужно будет установить индекс в качестве предварительного шага, используя DataFrame.set_index.


Фактически с использованием именованного индекса [pandas> = 0,23]

Если ваш индекс назван, то из pandas> = 0.23, DataFrame.merge позволяет вам указать имя индекса для on (или left_on и right_on, если необходимо).

left.merge(right, on='idxkey')

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135

Для предыдущего примера слияния с индексом левого столбца справа вы можете использовать left_on с именем индекса left:

left.merge(right2, left_on='idxkey', right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135


Продолжить чтение

Перейдите к другим темам в Pandas Merging 101, чтобы продолжить обучение:

* you are here

Присоединяется к 101

Эти анимации, возможно, лучше объяснят вам визуально. Кредиты: Garrick Aden-Buie tidyexplain репо

Внутреннее соединение

Внешнее соединение или полное соединение

Правое соединение

Левое соединение

Это круто!

Talha Tayyab 01.12.2021 05:05

Другие вопросы по теме