Панды собирают данные из двух фреймов данных

1

У меня есть два кадра данных 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'])
Теги:
pandas

2 ответа

2

Вот три возможности:

  • Используйте 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)')

Изображение 174551

  • 0
    это круто, работает как мне нужно!
0

Не видя кода, я могу дать общий ответ:

Чтобы объединить 2 кадра данных, используйте

df3 = pd.merge(df1, df2, how='right', on=('col1', 'col2'))

или же

a.merge(b, how='right', on=('c1', 'c2'))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню