df_join = DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False, validate=None)
other
- DataFrame
, Series
или список, содержащий любую их комбинацию. Индексом должен быть одним из столбцов. Если передается Series
, то должен быть установлен его атрибут Series.name
, который будет использоваться в качестве имени столбца в результирующем объединенном DataFrame
.
on=None
- строка с именем столбца, список имен столбцов или уровней индекса в исходном/вызывающем DataFrame
для присоединения к индексу в other
, в противном случае присоединяются индекс к индексу. Если задано несколько значений, то другой DataFrame
(other
) должен иметь MultiIndex
. Можно передать массив в качестве ключа соединения, если он еще не содержится в вызывающем DataFrame
. Типа операции VLOOKUP
в Excel.
Не поддерживаются при передаче списка объектов в
other
.
how='left'
- управляет объединением двух объектов.
Принимает следующие строки:
left
: использовать индекс вызывающего DataFrame
(или столбец, если указан on
)right
: использовать индекс other
.outer
: сформировать объединение индекса вызывающего DataFrame
(или столбца, если указан on
) с индексом other
и отсортировать его лексикографически.inner
: форма пересечения индекса вызывающего DataFrame
(или столбца, если указан on
) с индексом other
, при этом сохранить порядок вызывающего DataFrame
.cross
: создает декартово произведение из обоих DataFrame
, сохраняет порядок левых ключей.lsuffix=''
- суффикс, используемый из перекрывающихся столбцов левого DataFrame
. Не поддерживаются при передаче списка объектов в other
.
rsuffix=''
- суффикс, используемый из перекрывающихся столбцов правого DataFrame
. Не поддерживаются при передаче списка объектов в other
.
sort=False
- сортирует результат DataFrame
лексикографически по ключу соединения. Если задано значение False
, порядок ключа зависит от типа соединения (аргумент how
).
validate=None
- если указано, то проверяет, имеет ли соединение указанный тип.
Принимает следующие строки:
'one_to_one'
или '1:1'
: проверяет, уникальны ли ключи соединения как в левом, так и в правом наборах данных.'one_to_many'
или '1:m'
: проверяет, уникальны ли ключи соединения в левом наборе данных.'many_to_one'
или 'm:1'
: проверяет, уникальны ли ключи соединения в правом наборе данных.'many_to_many'
или 'm:m'
: допускается, но не приводит к проверкам.DataFrame.join()
Метод DataFrame.join()
модуля pandas
эффективно объединяет столбцы с другим DataFrame
либо по индексу, либо по ключевому столбцу. Поддерживает объединение по индексу, одновременно с несколькими объектами DataFrame/Series
.
Другими словами - это удобный метод объединения столбцов двух потенциально по-разному индексированных DataFrame
в единый результирующий фрейм данных.
Простой пример:
>>> import pandas as pd left = pd.DataFrame( {"A": ["A0", "A1", "A2"], "B": ["B0", "B1", "B2"]}, index=["K0", "K1", "K2"] ) right = pd.DataFrame( {"C": ["C0", "C2", "C3"], "D": ["D0", "D2", "D3"]}, index=["K0", "K2", "K3"] ) >>> left.join(right) # A B C D # K0 A0 B0 C0 D0 # K1 A1 B1 NaN NaN # K2 A2 B2 C2 D2
То же, что и выше, только с аргументом how="inner"
(пересечения индекса)
>>> left.join(right, how="inner") # A B C D # K0 A0 B0 C0 D0 # K2 A2 B2 C2 D2
Метод DataFrame.join()
принимает необязательный аргумент on
, который может быть именем столбца или нескольких столбцов, и указывает, что переданный DataFrame
должен быть выровнен по этому столбцу. Следующие два вызова полностью эквивалентны:
# абстрактный код left.join(right, on=key_or_keys) # эквивалентно (вызов делает то-же самое) left.merge( right, left_on=key_or_keys, right_index=True, how="left", sort=False )
Для соединений 'many-to-one'
(когда один из DataFrame
уже проиндексирован по ключу соединения) использование метода DataFrame.join()
может быть более удобным. Простой пример:
>>> left = pd.DataFrame({"A": ["A0", "A1", "A2", "A3"], "B": ["B0", "B1", "B2", "B3"], ... "key": ["K0", "K1", "K0", "K1"],}) >>> right = pd.DataFrame({"C": ["C0", "C1"], "D": ["D0", "D1"]}, index=["K0", "K1"]) >>> left.join(right, on="key") # A B key C D # 0 A0 B0 K0 C0 D0 # 1 A1 B1 K1 C1 D1 # 2 A2 B2 K0 C0 D0 # 3 A3 B3 K1 C1 D1 >>> left.merge(right, left_on="key", right_index=True, how="left", sort=False) # A B key C D # 0 A0 B0 K0 C0 D0 # 1 A1 B1 K1 C1 D1 # 2 A2 B2 K0 C0 D0 # 3 A3 B3 K1 C1 D1
Для соединения по нескольким ключам, переданный DataFrame
должен иметь MultiIndex
. Для демонстрации примера создадим DataFrame
c MultiIndex
:
left = pd.DataFrame( { "A": ["A0", "A1", "A2", "A3"], "B": ["B0", "B1", "B2", "B3"], "key1": ["K0", "K0", "K1", "K2"], "key2": ["K0", "K1", "K0", "K1"], } ) index = pd.MultiIndex.from_tuples( [("K0", "K0"), ("K1", "K0"), ("K2", "K0"), ("K2", "K1")] ) right = pd.DataFrame( {"C": ["C0", "C1", "C2", "C3"], "D": ["D0", "D1", "D2", "D3"]}, index=index )
Теперь созданные DataFrame
можно соединить, передав два имени столбца, используемых как ключи аргумента on
:
>>> left.join(right, on=["key1", "key2"]) # A B key1 key2 C D # 0 A0 B0 K0 K0 C0 D0 # 1 A1 B1 K0 K1 NaN NaN # 2 A2 B2 K1 K0 C1 D1 # 3 A3 B3 K2 K1 C3 D3
По умолчанию для DataFrame.join()
выполняется левое соединение (по сути, операция VLOOKUP
в Excel), в котором используются только ключи, найденные в вызывающем DataFrame
. Другие типы соединений, например, внутреннее соединение, могут быть выполнены так же легко:
>>> left.join(right, on=["key1", "key2"], how="inner") # A B key1 key2 C D # 0 A0 B0 K0 K0 C0 D0 # 2 A2 B2 K1 K0 C1 D1 # 3 A3 B3 K2 K1 C3 D3
При этом отбрасываются все строки, в которых не было совпадений.
MultiIndex
DataFrame
с простым индексом можно объединить с помощью уровня MultiIndex
. Уровень будет совпадать по имени индекса простого DataFrame
с именем уровня MultiIndex
(другой DataFrame
).
left = pd.DataFrame( {"A": ["A0", "A1", "A2"], "B": ["B0", "B1", "B2"]}, index=pd.Index(["K0", "K1", "K2"], name="key"), ) index = pd.MultiIndex.from_tuples( [("K0", "Y0"), ("K1", "Y1"), ("K2", "Y2"), ("K2", "Y3")], names=["key", "Y"], ) right = pd.DataFrame( {"C": ["C0", "C1", "C2", "C3"], "D": ["D0", "D1", "D2", "D3"]}, index=index, ) >>> left.join(right, how="inner") # A B C D # key Y # K0 Y0 A0 B0 C0 D0 # K1 Y1 A1 B1 C1 D1 # K2 Y2 A2 B2 C2 D2 # Y3 A2 B2 C3 D3
DataFrame
с MultiIndex
Такое поведение поддерживается ограниченным образом, при условии, что индекс в правом DataFrame
полностью используется в соединении и является подмножеством индексов в левом DataFrame
, как в этом примере:
leftindex = pd.MultiIndex.from_product( [list("abc"), list("xy"), [1, 2]], names=["abc", "xy", "num"] ) >>> left = pd.DataFrame({"v1": range(12)}, index=leftindex) >>> left # v1 # abc xy num # a x 1 0 # 2 1 # y 1 2 # 2 3 # b x 1 4 # 2 5 # y 1 6 # 2 7 # c x 1 8 # 2 9 # y 1 10 # 2 11 rightindex = pd.MultiIndex.from_product( [list("abc"), list("xy")], names=["abc", "xy"] ) >>> right = pd.DataFrame({"v2": [100 * i for i in range(1, 7)]}, index=rightindex) >>> right # v2 # abc xy # a x 100 # y 200 # b x 300 # y 400 # c x 500 # y 600 left.join(right, on=["abc", "xy"], how="inner") # v1 v2 # abc xy num # a x 1 0 100 # 2 1 100 # y 1 2 200 # 2 3 200 # b x 1 4 300 # 2 5 300 # y 1 6 400 # 2 7 400 # c x 1 8 500 # 2 9 500 # y 1 10 600 # 2 11 600
Если это условие не выполняется, соединение двух DataFrame
, имеющих MultiIndex
можно выполнить с помощью DataFrame.merge()
.
leftindex = pd.MultiIndex.from_tuples( [("K0", "X0"), ("K0", "X1"), ("K1", "X2")], names=["key", "X"] ) left = pd.DataFrame( {"A": ["A0", "A1", "A2"], "B": ["B0", "B1", "B2"]}, index=leftindex ) rightindex = pd.MultiIndex.from_tuples( [("K0", "Y0"), ("K1", "Y1"), ("K2", "Y2"), ("K2", "Y3")], names=["key", "Y"] ) right = pd.DataFrame( {"C": ["C0", "C1", "C2", "C3"], "D": ["D0", "D1", "D2", "D3"]}, index=rightindex ) >>> left.reset_index().merge(right.reset_index(), on=["key"], how="inner").set_index(["key", "X", "Y"]) # A B C D # key X Y # K0 X0 Y0 A0 B0 C0 D0 # X1 Y0 A1 B1 C0 D0 # K1 X2 Y1 A2 B2 C1 D1
Дополнительно смотрите материал "Сравнение pandas с SQL".
DataFrame.join()
:Необходимо помнить, что аргументы
on
,lsuffix
иrsuffix
не поддерживаются при передаче списка объектовDataFrame
аргументуother
.
Создадим два DataFrame
, с которыми будем работать:
import pandas as pd df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'], 'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']}) other = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'B': ['B0', 'B1', 'B2']}) >>> df # key A # 0 K0 A0 # 1 K1 A1 # 2 K2 A2 # 3 K3 A3 # 4 K4 A4 # 5 K5 A5 >>> other # key B # 0 K0 B0 # 1 K1 B1 # 2 K2 B2
Присоединим other
к df
, используя их индексы.
>>> df.join(other, lsuffix='_caller', rsuffix='_other') # key_caller A key_other B # 0 K0 A0 K0 B0 # 1 K1 A1 K1 B1 # 2 K2 A2 K2 B2 # 3 K3 A3 NaN NaN # 4 K4 A4 NaN NaN # 5 K5 A5 NaN NaN
Если необходимо объединение, используя ключевые столбцы, то нужно установить ключ в качестве индекса как в df
, так и в other
. Результирующий DataFrame
будет иметь в качестве индекса - ключ.
>>> df.set_index('key').join(other.set_index('key')) # A B # key # K0 A0 B0 # K1 A1 B1 # K2 A2 B2 # K3 A3 NaN # K4 A4 NaN # K5 A5 NaN
Другой вариант объединения с использованием ключевых столбцов - использование аргумента on
. DataFrame.join()
всегда использует индекс из other
, при этом можно указать (аргумент on
) любой столбец (в качестве ключа) из df
. В результате, метод сохранит индекс исходного DataFrame
.
>>> df.join(other.set_index('key'), on='key') # key A B # 0 K0 A0 B0 # 1 K1 A1 B1 # 2 K2 A2 B2 # 3 K3 A3 NaN # 4 K4 A4 NaN # 5 K5 A5 NaN
Объединение DataFrame
, у которых есть повторяющиеся (неуникальные) значения ключа. Смотрим как они сопоставляются. Для этого создадим DataFrame
с повторяющимися значениями:
df = pd.DataFrame({'key': ['K0', 'K1', 'K1', 'K3', 'K0', 'K1'], 'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']}) >>> df # key A # 0 K0 A0 # 1 K1 A1 # 2 K1 A2 # 3 K3 A3 # 4 K0 A4 # 5 K1 A5 >>> other # key B # 0 K0 B0 # 1 K1 B1 # 2 K2 B2 # объединяем >>> df.join(other.set_index('key'), on='key', validate='m:1') # key A B # 0 K0 A0 B0 # 1 K1 A1 B1 # 2 K1 A2 B1 # 3 K3 A3 NaN # 4 K0 A4 B0 # 5 K1 A5 B1