Объединение, присоединение и конкатенация
pandas предоставляет различные средства для лёгкого объединения объектов Series, DataFrame и Panel с различными типами логических операций над индексами и функциональностью реляционной алгебры в случае операций типа присоединения/слияния.
Конкатенация объектов
Функция concat (в основном пространстве имён pandas) выполняет все основные операции конкатенации вдоль оси, выполняя при этом опциональные логические операции (объединение или пересечение) индексов (если таковые имеются) на других осях. Обратите внимание, что я говорю «если таковые имеются», потому что для Series существует только одна возможная ось конкатенации.
Прежде чем углубиться во все детали concat и его возможности, вот простой пример:
In [1]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
...: 'B': ['B0', 'B1', 'B2', 'B3'],
...: 'C': ['C0', 'C1', 'C2', 'C3'],
...: 'D': ['D0', 'D1', 'D2', 'D3']},
...: index=[0, 1, 2, 3])
...:
In [2]: df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
...: 'B': ['B4', 'B5', 'B6', 'B7'],
...: 'C': ['C4', 'C5', 'C6', 'C7'],
...: 'D': ['D4', 'D5', 'D6', 'D7']},
...: index=[4, 5, 6, 7])
...:
In [3]: df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
...: 'B': ['B8', 'B9', 'B10', 'B11'],
...: 'C': ['C8', 'C9', 'C10', 'C11'],
...: 'D': ['D8', 'D9', 'D10', 'D11']},
...: index=[8, 9, 10, 11])
...:
In [4]: frames = [df1, df2, df3]
In [5]: result = pd.concat(frames)
Как и её аналог для массивов ndarrays, numpy.concatenate, pandas.concat принимает список или словарь однородных объектов и конкатенирует их с некоторым настраиваемым обработкой «чего делать с другими осями»:
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False)
-
objs: последовательность или отображение объектов Series, DataFrame или Panel. Если передан словарь, отсортированные ключи будут использоваться в качестве аргументаkeys, если он не передан, в противном случае будут выбраны значения (см. ниже). Любые объекты None будут удалены безмолвно, за исключением случая, когда все они равны None, в этом случае будет поднято исключение ValueError. -
axis: {0, 1, ...}, по умолчанию 0. Ось, по которой выполняется конкатенация. -
join: {‘inner’, ‘outer’}, по умолчанию ‘outer’. Способ обработки индексов на других осях. Outer для объединения и inner для пересечения. -
join_axes: список объектов Index. Конкретные индексы для использования на других осях n - 1 вместо выполнения логических операций inner/outer. -
keys: последовательность, по умолчанию None. Построение иерархического индекса с использованием переданных ключей как внешнего уровня. Если передано несколько уровней, оно должно содержать кортежи. -
levels: список последовательностей, по умолчанию None. Конкретные уровни (уникальные значения) для использования при построении MultiIndex. В противном случае они будут выведены из ключей. -
names: список, по умолчанию None. Имена уровней в результирующем иерархическом индексе. -
verify_integrity: булево значение, по умолчанию False. Проверка на наличие дубликатов в новой оси конкатенации. Это может быть очень дорого по сравнению с фактической конкатенацией данных. -
ignore_index: булево значение, по умолчанию False. Если True, не использовать значения индексов на оси конкатенации. Результирующая ось будет помечена 0, ..., n - 1. Это полезно, если вы конкатенируете объекты, где ось конкатенации не имеет осмысленной информации об индексации. Обратите внимание, что значения индексов на других осях по-прежнему учитываются при объединении. -
copy: булево значение, по умолчанию True. Если False, не копировать данные излишне.
Без небольшого контекста и примера многие из этих аргументов не имеют большого смысла. Давайте рассмотрим вышеприведённый пример. Предположим, что мы хотели связать конкретные ключи с каждой частью разбитого DataFrame. Мы можем сделать это, используя аргумент keys.
In [6]: result = pd.concat(frames, keys=['x', 'y', 'z'])
Как вы можете видеть (если вы прочитали остальную часть документации), индекс результирующего объекта имеет иерархический индекс. Это означает, что теперь мы можем выполнять такие действия, как выделение каждого фрагмента по ключу:
In [7]: result.ix['y']
Out[7]:
A B C D
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
Несложно понять, как это может быть очень полезно. Более подробные сведения об этой функциональности приведены ниже.
Примечание
Стоит отметить, что concat (и, следовательно, append) делает полную копию данных, и постоянное повторное использование этой функции может привести к существенной потере производительности. Если вам нужно использовать операцию над несколькими наборами данных, используйте список понимания.
frames = [ process_your_file(f) for f in files ] result = pd.concat(frames)
Логические операции над другими осями
При склеивании нескольких DataFrame (или Panel и т.д.) у вас есть выбор, как обрабатывать другие оси (кроме той, по которой выполняется конкатенация). Это можно сделать тремя способами:
- Взять (отсортированное) объединение всех из них,
join='outer'. Это вариант по умолчанию, так как он приводит к нулевым потерям информации. - Взять пересечение,
join='inner'. - Использовать определённый индекс (в случае DataFrame) или индексы (в случае Panel или будущих объектов более высокой размерности), т.е. аргумент
join_axes
Вот пример каждого из этих методов. Сначала поведение по умолчанию join='outer':
In [8]: df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],
...: 'D': ['D2', 'D3', 'D6', 'D7'],
...: 'F': ['F2', 'F3', 'F6', 'F7']},
...: index=[2, 3, 6, 7])
...:
In [9]: result = pd.concat([df1, df4], axis=1)
Обратите внимание, что индексы строк были объединены и отсортированы. Вот то же самое с join='inner':
In [10]: result = pd.concat([df1, df4], axis=1, join='inner')
Наконец, предположим, что мы просто хотели использовать точный индекс из исходного DataFrame:
In [11]: result = pd.concat([df1, df4], axis=1, join_axes=[df1.index])
Конкатенация с помощью append
Полезным сокращением для concat являются методы экземпляра append для Series и DataFrame. Эти методы фактически предшествовали concat . Они конкатенируют вдоль axis=0, а именно индекса:
In [12]: result = df1.append(df2)
В случае DataFrame индексы должны быть непересекающимися, но столбцы не обязательно должны быть:
In [13]: result = df1.append(df4)
append может принимать несколько объектов для конкатенации:
In [14]: result = df1.append([df2, df3])
Примечание
В отличие от метода list.append, который добавляет в исходный список и ничего не возвращает, append здесь **не** изменяет df1 и возвращает его копию с добавленным df2.
Игнорирование индексов на оси конкатенации
Для DataFrame, у которых нет осмысленного индекса, вы можете добавить их, игнорируя тот факт, что у них могут быть перекрывающиеся индексы:
Для этого используйте аргумент ignore_index:
In [15]: result = pd.concat([df1, df4], ignore_index=True)
Это также допустимый аргумент для DataFrame.append:
In [16]: result = df1.append(df4, ignore_index=True)
Конкатенация с различными измерениями
Вы можете конкатенировать смесь Series и DataFrame. Series будут преобразованы в DataFrame со именем столбца как именем Series.
In [17]: s1 = pd.Series(['X0', 'X1', 'X2', 'X3'], name='X') In [18]: result = pd.concat([df1, s1], axis=1)
Если переданы неименованные Series, они будут пронумерованы последовательно.
In [19]: s2 = pd.Series(['_0', '_1', '_2', '_3']) In [20]: result = pd.concat([df1, s2, s2, s2], axis=1)
Передача ignore_index=True удалит все ссылки на имена.
In [21]: result = pd.concat([df1, s1], axis=1, ignore_index=True)
Дополнительная конкатенация с ключами групп
Довольно распространённое использование аргумента keys заключается в перезаписи имён столбцов при создании нового DataFrame на основе существующих Series. Обратите внимание, как поведение по умолчанию состоит в том, чтобы позволить результирующему DataFrame унаследовать имя родительской Series, если они существовали.
In [22]: s3 = pd.Series([0, 1, 2, 3], name='foo') In [23]: s4 = pd.Series([0, 1, 2, 3]) In [24]: s5 = pd.Series([0, 1, 4, 5]) In [25]: pd.concat([s3, s4, s5], axis=1) Out[25]: foo 0 1 0 0 0 0 1 1 1 1 2 2 2 4 3 3 3 5
С помощью аргумента keys мы можем перезаписать существующие имена столбцов.
In [26]: pd.concat([s3, s4, s5], axis=1, keys=['red','blue','yellow']) Out[26]: red blue yellow 0 0 0 0 1 1 1 1 2 2 2 4 3 3 3 5
Давайте рассмотрим теперь вариацию на самом первом представленном примере:
In [27]: result = pd.concat(frames, keys=['x', 'y', 'z'])
Вы также можете передать словарь в concat, в этом случае ключи словаря будут использоваться в качестве аргумента keys (если не указаны другие ключи):
In [28]: pieces = {'x': df1, 'y': df2, 'z': df3}
In [29]: result = pd.concat(pieces)
In [30]: result = pd.concat(pieces, keys=['z', 'y'])
Созданный MultiIndex имеет уровни, построенные из переданных ключей и индекса фрагментов DataFrame:
In [31]: result.index.levels Out[31]: FrozenList([[u'z', u'y'], [4, 5, 6, 7, 8, 9, 10, 11]])
Если вы хотите указать другие уровни (что иногда бывает необходимо), вы можете сделать это, используя аргумент levels:
In [32]: result = pd.concat(pieces, keys=['x', 'y', 'z'], ....: levels=[['z', 'y', 'x', 'w']], ....: names=['group_key']) ....:
In [33]: result.index.levels Out[33]: FrozenList([[u'z', u'y', u'x', u'w'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])
Да, это довольно экзотично, но на самом деле необходимо для реализации таких вещей, как GroupBy, где порядок категориальной переменной имеет значение.
Добавление строк в DataFrame
Хотя это не особенно эффективно (поскольку должен быть создан новый объект), вы можете добавить одну строку в DataFrame, передав Series или словарь в append, что возвращает новый DataFrame, как и выше.
In [34]: s2 = pd.Series(['X0', 'X1', 'X2', 'X3'], index=['A', 'B', 'C', 'D']) In [35]: result = df1.append(s2, ignore_index=True)
Вы должны использовать ignore_index с этим методом, чтобы указать DataFrame на отбрасывание его индекса. Если вы хотите сохранить индекс, вы должны создать DataFrame с соответствующим индексом и добавить или конкатенировать эти объекты.
Вы также можете передать список словарей или Series:
In [36]: dicts = [{'A': 1, 'B': 2, 'C': 3, 'X': 4},
....: {'A': 5, 'B': 6, 'C': 7, 'Y': 8}]
....:
In [37]: result = df1.append(dicts, ignore_index=True)
Объединение/слияние DataFrame в стиле баз данных
pandas имеет полнофункциональные, высокопроизводительные операции объединения в памяти, очень похожие по стилю на реляционные базы данных, такие как SQL. Эти методы работают значительно лучше (в некоторых случаях на порядок лучше), чем другие реализации с открытым исходным кодом (например, base::merge.data.frame в R). Причина в продуманном алгоритмическом проектировании и внутренней структуре данных в DataFrame.
См. справочник по рецептам для некоторых расширенных стратегий.
Пользователи, знакомые с SQL, но новые для pandas, могут быть заинтересованы в сравнении с SQL.
pandas предоставляет одну функцию, merge, как точку входа для всех стандартных операций объединения баз данных между объектами DataFrame:
merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=('_x', '_y'), copy=True, indicator=False)
Вот описание того, для чего предназначен каждый аргумент:
-
left: Объект DataFrame -
right: Другой объект DataFrame -
on: Столбцы (имена) для объединения. Должны присутствовать в обоих объектах DataFrame. Если не передано, иleft_indexиright_indexимеют значениеFalse, пересечение столбцов в объектах DataFrame будет определено в качестве ключей объединения -
left_on: Столбцы из левого объекта DataFrame для использования в качестве ключей. Могут быть именами столбцов или массивами с длиной, равной длине DataFrame -
right_on: Столбцы из правого объекта DataFrame для использования в качестве ключей. Могут быть именами столбцов или массивами с длиной, равной длине DataFrame -
left_index: ЕслиTrue, использовать индекс (метки строк) из левого объекта DataFrame в качестве ключа(ей) объединения. В случае DataFrame с MultiIndex (иерархическим), количество уровней должно соответствовать количеству ключей объединения из правого DataFrame -
right_index: Аналогичное использование, как уleft_indexдля правого DataFrame -
how: Один из'left','right','outer','inner'. По умолчаниюinner. См. более подробное описание каждого метода ниже -
sort: Отсортировать результирующий DataFrame по ключам объединения в лексикографическом порядке. По умолчаниюTrue, установка значенияFalseсущественно улучшит производительность во многих случаях -
suffixes: Кортеж строчных суффиксов для применения к перекрывающимся столбцам. По умолчанию('_x', '_y'). -
copy: Всегда копировать данные (по умолчаниюTrue) из переданных объектов DataFrame, даже когда переиндексация не требуется. В многих случаях этого избежать нельзя, но эта опция может улучшить производительность/использование памяти. Случаи, когда копирование можно избежать, являются несколько патологическими, но эта опция всё же предоставляется. -
indicator: Добавить столбец в результирующий DataFrame под названием_mergeсо сведениями о источнике каждой строки._mergeимеет тип Categorical и принимает значениеleft_onlyдля наблюдений, ключ объединения которых встречается только в'left'DataFrame,right_onlyдля наблюдений, ключ объединения которых встречается только в'right'DataFrame, иbothесли ключ объединения наблюдения найден в обоих.Добавлена в версии 0.17.0.
Тип возвращаемого значения будет таким же, как у left. Если left является DataFrame и right является подклассом DataFrame, тип возвращаемого значения всё ещё будет DataFrame.
merge — функция в пространстве имён pandas, и она также доступна в качестве метода экземпляра DataFrame, при этом вызываемый DataFrame неявно рассматривается как левый объект в объединении.
Связанный метод DataFrame.join, использует merge в качестве внутреннего метода для объединений по индексу и по столбцу(ам), но по умолчанию объединяет по индексам, а не по общим столбцам (по умолчанию для merge). Если вы объединяете по индексу, вы можете воспользоваться DataFrame.join, чтобы сэкономить на наборе.
Краткий обзор методов объединения (реляционная алгебра)
Опытные пользователи реляционных баз данных, таких как SQL, будут знакомы с терминологией, используемой для описания операций объединения между двумя структурами типа SQL-таблицы (объекты DataFrame). Следует рассмотреть несколько случаев, которые очень важно понять:
- Один-к-одному объединение: например, при объединении двух объектов DataFrame по их индексам (которые должны содержать уникальные значения)
- Много-к-одному объединение: например, при объединении индекса (уникального) с одним или несколькими столбцами в DataFrame
- Много-ко-многим объединение: объединение столбцов со столбцами.
Примечание
При объединении столбцов со столбцами (потенциально много-ко-многим объединении), любые индексы в переданных объектах DataFrame будут удалены.
Стоит потратить некоторое время на понимание результата случая много-ко-многим объединения. В SQL/стандартной реляционной алгебре, если комбинация ключей встречается более одного раза в обеих таблицах, результирующая таблица будет содержать декартово произведение связанных данных. Вот очень простой пример с одной уникальной комбинацией ключей:
In [38]: left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
....: 'A': ['A0', 'A1', 'A2', 'A3'],
....: 'B': ['B0', 'B1', 'B2', 'B3']})
....:
In [39]: right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
....: 'C': ['C0', 'C1', 'C2', 'C3'],
....: 'D': ['D0', 'D1', 'D2', 'D3']})
....:
In [40]: result = pd.merge(left, right, on='key')
Вот более сложный пример с несколькими ключами объединения:
In [41]: left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
....: 'key2': ['K0', 'K1', 'K0', 'K1'],
....: 'A': ['A0', 'A1', 'A2', 'A3'],
....: 'B': ['B0', 'B1', 'B2', 'B3']})
....:
In [42]: right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
....: 'key2': ['K0', 'K0', 'K0', 'K0'],
....: 'C': ['C0', 'C1', 'C2', 'C3'],
....: 'D': ['D0', 'D1', 'D2', 'D3']})
....:
In [43]: result = pd.merge(left, right, on=['key1', 'key2'])
Аргумент how к merge определяет, как определить, какие ключи должны быть включены в результирующую таблицу. Если комбинация ключей не встречается ни в левой, ни в правой таблицах, значения в объединённой таблице будут NA. Вот сводка вариантов how и их эквивалентов в SQL:
| Метод объединения | Название объединения SQL | Описание |
|---|---|---|
left | LEFT OUTER JOIN | Использовать ключи только из левой таблицы |
right | RIGHT OUTER JOIN | Использовать ключи только из правой таблицы |
outer | FULL OUTER JOIN | Использовать объединение ключей из обеих таблиц |
inner | INNER JOIN | Использовать пересечение ключей из обеих таблиц |
In [44]: result = pd.merge(left, right, how='left', on=['key1', 'key2'])
In [45]: result = pd.merge(left, right, how='right', on=['key1', 'key2'])
In [46]: result = pd.merge(left, right, how='outer', on=['key1', 'key2'])
In [47]: result = pd.merge(left, right, how='inner', on=['key1', 'key2'])
Индикатор объединения
Добавлена в версии 0.17.0.
merge теперь принимает аргумент indicator. Если True, столбец типа Categorical под названием _merge будет добавлен к выходному объекту, принимая значения:
| Происхождение наблюдения |
_merge значение |
|---|---|
Ключ объединения только в 'left' таблице | left_only |
Ключ объединения только в 'right' таблице | right_only |
| Ключ объединения в обеих таблицах | both |
In [48]: df1 = DataFrame({'col1':[0,1], 'col_left':['a','b']})
In [49]: df2 = DataFrame({'col1':[1,2,2],'col_right':[2,2,2]})
In [50]: merge(df1, df2, on='col1', how='outer', indicator=True)
Out[50]:
col1 col_left col_right _merge
0 0.0 a NaN left_only
1 1.0 b 2.0 both
2 2.0 NaN 2.0 right_only
3 2.0 NaN 2.0 right_only
Аргумент indicator также принимает строковые аргументы, в этом случае функция индикатора будет использовать значение переданной строки в качестве имени столбца-индикатора.
In [51]: merge(df1, df2, on='col1', how='outer', indicator='indicator_column') Out[51]: col1 col_left col_right indicator_column 0 0.0 a NaN left_only 1 1.0 b 2.0 both 2 2.0 NaN 2.0 right_only 3 2.0 NaN 2.0 right_only
Объединение по индексу
DataFrame.join — удобный метод для объединения столбцов двух потенциально имеющих разные индексы DataFrame в единый результирующий DataFrame. Вот очень простой пример:
In [52]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
....: 'B': ['B0', 'B1', 'B2']},
....: index=['K0', 'K1', 'K2'])
....:
In [53]: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
....: 'D': ['D0', 'D2', 'D3']},
....: index=['K0', 'K2', 'K3'])
....:
In [54]: result = left.join(right)
In [55]: result = left.join(right, how='outer')
In [56]: result = left.join(right, how='inner')
Выравнивание данных происходит по индексам (меткам строк). То же самое поведение можно получить, используя merge вместе с дополнительными аргументами, указывающими на использование индексов:
In [57]: result = pd.merge(left, right, left_index=True, right_index=True, how='outer')
In [58]: result = pd.merge(left, right, left_index=True, right_index=True, how='inner');
Объединение столбцов ключей по индексу
join принимает необязательный аргумент on, который может быть именем столбца или нескольких столбцов, указывающий, что переданный DataFrame будет выровнен по этому столбцу в DataFrame. Эти два вызова функции полностью эквивалентны:
left.join(right, on=key_or_keys)
pd.merge(left, right, left_on=key_or_keys, right_index=True,
how='left', sort=False)
Конечно, вы можете выбрать любую форму, которая вам удобнее. Для объединений много-к-одному (где один из DataFrame уже индексирован по ключу объединения), использование join может быть удобнее. Вот простой пример:
In [59]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
....: 'B': ['B0', 'B1', 'B2', 'B3'],
....: 'key': ['K0', 'K1', 'K0', 'K1']})
....:
In [60]: right = pd.DataFrame({'C': ['C0', 'C1'],
....: 'D': ['D0', 'D1']},
....: index=['K0', 'K1'])
....:
In [61]: result = left.join(right, on='key')
In [62]: result = pd.merge(left, right, left_on='key', right_index=True, ....: how='left', sort=False); ....:
Для объединения по нескольким ключам, переданный DataFrame должен иметь MultiIndex:
In [63]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
....: 'B': ['B0', 'B1', 'B2', 'B3'],
....: 'key1': ['K0', 'K0', 'K1', 'K2'],
....: 'key2': ['K0', 'K1', 'K0', 'K1']})
....:
In [64]: index = pd.MultiIndex.from_tuples([('K0', 'K0'), ('K1', 'K0'),
....: ('K2', 'K0'), ('K2', 'K1')])
....:
In [65]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
....: 'D': ['D0', 'D1', 'D2', 'D3']},
....: index=index)
....:
Теперь это можно объединить, передав имена двух столбцов ключей:
In [66]: result = left.join(right, on=['key1', 'key2'])
По умолчанию для DataFrame.join выполняется левое объединение (по сути, операция «VLOOKUP», для пользователей Excel), которое использует только ключи, найденные в вызываемом DataFrame. Другие типы объединений, например, внутреннее объединение, могут быть выполнены так же легко:
In [67]: result = left.join(right, on=['key1', 'key2'], how='inner')
Как видно, это отбрасывает строки, где не было совпадений.
Объединение по единственному индексу с многоуровневым индексом
Добавлена в версии 0.14.0.
Вы можете объединить DataFrame с одиночным индексом DataFrame с уровнем многоуровневого индекса DataFrame. Уровень будет совпадать по имени индекса одиночного DataFrame с именем уровня многоуровневого DataFrame.
In [68]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
....: 'B': ['B0', 'B1', 'B2']},
....: index=Index(['K0', 'K1', 'K2'], name='key'))
....:
In [69]: index = pd.MultiIndex.from_tuples([('K0', 'Y0'), ('K1', 'Y1'),
....: ('K2', 'Y2'), ('K2', 'Y3')],
....: names=['key', 'Y'])
....:
In [70]: right = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
....: 'D': ['D0', 'D1', 'D2', 'D3']},
....: index=index)
....:
In [71]: result = left.join(right, how='inner')
Это эквивалентно, но менее громоздко и более эффективно с точки зрения памяти/скорее, чем это.
In [72]: result = pd.merge(left.reset_index(), right.reset_index(), ....: on=['key'], how='inner').set_index(['key','Y']) ....:
Объединение с двумя многоуровневыми индексами
В данный момент это не реализовано через join, однако это можно сделать следующим образом.
In [73]: index = pd.MultiIndex.from_tuples([('K0', 'X0'), ('K0', 'X1'),
....: ('K1', 'X2')],
....: names=['key', 'X'])
....:
In [74]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
....: 'B': ['B0', 'B1', 'B2']},
....: index=index)
....:
In [75]: result = pd.merge(left.reset_index(), right.reset_index(),
....: on=['key'], how='inner').set_index(['key','X','Y'])
....:
Перекрывающиеся столбцы значений
Аргумент объединения suffixes принимает кортеж списков строк, которые добавляются к именам перекрывающихся столбцов в исходных DataFrame, чтобы отличить результирующие столбцы:
In [76]: left = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'v': [1, 2, 3]})
In [77]: right = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'v': [4, 5, 6]})
In [78]: result = pd.merge(left, right, on='k')
In [79]: result = pd.merge(left, right, on='k', suffixes=['_l', '_r'])
DataFrame.join имеет аргументы lsuffix и rsuffix, которые ведут себя аналогично.
In [80]: left = left.set_index('k')
In [81]: right = right.set_index('k')
In [82]: result = left.join(right, lsuffix='_l', rsuffix='_r')
Объединение нескольких объектов DataFrame или Panel
Список или кортеж DataFrame также может быть передан в DataFrame.join для объединения их вместе по своим индексам. То же самое верно для Panel.join.
In [83]: right2 = pd.DataFrame({'v': [7, 8, 9]}, index=['K1', 'K1', 'K2'])
In [84]: result = left.join([right, right2])
Объединение упорядоченных данных
Новым в версии v0.8.0 является функция ordered_merge для объединения временных рядов и других упорядоченных данных. В частности, она имеет необязательный аргумент fill_method для заполнения/интерполяции пропущенных данных:
In [85]: left = DataFrame({'k': ['K0', 'K1', 'K1', 'K2'],
....: 'lv': [1, 2, 3, 4],
....: 's': ['a', 'b', 'c', 'd']})
....:
In [86]: right = DataFrame({'k': ['K1', 'K2', 'K4'],
....: 'rv': [1, 2, 3]})
....:
In [87]: result = ordered_merge(left, right, fill_method='ffill', left_by='s')
Объединение значений в столбцах Series или DataFrame
Еще одна довольно распространенная ситуация — это наличие двух объектов Series или DataFrame с одинаковыми индексами (или аналогичными индексами), и желание «заменить» значения в одном объекте значениями для соответствующих индексов в другом. Вот пример:
In [88]: df1 = pd.DataFrame([[np.nan, 3., 5.], [-4.6, np.nan, np.nan], ....: [np.nan, 7., np.nan]]) ....: In [89]: df2 = pd.DataFrame([[-42.6, np.nan, -8.2], [-5., 1.6, 4]], ....: index=[1, 2]) ....:
Для этого используйте метод combine_first.
In [90]: result = df1.combine_first(df2)
Обратите внимание, что этот метод берет значения только из правой DataFrame, если они отсутствуют в левой DataFrame. Связанный метод, update, изменяет значения, отличные от NA, на месте:
In [91]: df1.update(df2)
© 2008–2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/0.18.1/merging.html