У меня есть два кадра данных pandas, с некоторыми индексами и с некоторыми именами столбцов (например, частично перекрывающиеся временные ряды, связанные с общими количествами).
Мне нужно объединить эти два фрейма данных в одном, содержащем все индексы и все значения для каждого индекса, сохраняя значения слева (справа), если комбинация индекс-столбец появится в обоих кадрах данных.
Оба метода объединения и объединения бесполезны, поскольку метод слияния дублирует информацию, которая мне не нужна, и соединение вызывает ту же проблему.
Какой эффективный метод для получения результата, который мне нужен?
EDIT: Если, например, у меня есть два кадра данных
df1 = pd.DataFrame({
'C1' : [1.1, 1.2, 1.3],
'C2' : [2.1, 2.2, 2.3],
'C3': [3.1, 3.2, 3.3]},
index=['a', 'b', 'c'])
df2 = pd.DataFrame({
'C3' : [3.1, 3.2, 33.3],
'C4' : [4.1, 4.2, 4.3]},
index=['b', 'c', 'd'])
Мне нужен метод, который позволяет мне создавать:
merged = pd.DataFrame({
'C1': [1.1, 1.2, 1.3, 'nan'],
'C2': [2.1, 2.2, 2.3, 'nan'],
'C3': [3.1, 3.2, 3.3, 33.3],
'C4': ['nan', 4.1, 4.2, 4.3]},
index=['a', 'b', 'c', 'd'])
Вот три возможности:
Используйте concat/groupby
: сначала объединяйте оба DataFrames по вертикали. Затем группируйте по индексу и выберите первую строку в каждой группе.
Используйте combine_first
: создайте новый индекс, который является объединением df1
и df2
. Reindex df1
с использованием нового индекса. Затем используйте combine_first
чтобы заполнить NaN со значениями из df2
.
Используйте ручную конструкцию: мы можем использовать df2.index.difference(df1.index)
чтобы точно df2.index.difference(df1.index)
, какие строки нужно добавить в df1
. Таким образом, мы могли бы вручную выбрать эти строки из df2
и df2
их в df1
.
Для небольших DataFrames using_concat
работает быстрее. Для более крупных DataFrames using_combine_first
выглядит немного быстрее, чем другие параметры:
import numpy as np
import pandas as pd
import perfplot
def make_dfs(N):
df1 = pd.DataFrame(np.random.randint(10, size=(N,2)))
df2 = pd.DataFrame(np.random.randint(10, size=(N,2)), index=range(N//2,N//2 + N))
return df1, df2
def using_concat(dfs):
df1, df2 = dfs
result = pd.concat([df1,df2], sort=False)
n = result.index.nlevels
return result.groupby(level=range(n)).first()
def using_combine_first(dfs):
df1, df2 = dfs
index = df1.index.union(df2.index)
result = df1.reindex(index)
result = result.combine_first(df2)
return result
def using_manual_construction(dfs):
df1, df2 = dfs
index = df2.index.difference(df1.index)
cols = df2.columns.difference(df1.columns)
result = pd.concat([df1, df2.loc[index]], sort=False)
result.loc[df2.index, cols] = df2
return result
perfplot.show(
setup=make_dfs,
kernels=[using_concat, using_combine_first,
using_manual_construction],
n_range=[2**k for k in range(5,21)],
logx=True,
logy=True,
xlabel='len(df)')
Не видя кода, я могу дать общий ответ:
Чтобы объединить 2 кадра данных, используйте
df3 = pd.merge(df1, df2, how='right', on=('col1', 'col2'))
или же
a.merge(b, how='right', on=('c1', 'c2'))