Как избежать декартовой системы при слиянии в Pandas Python - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь объединить 2 набора данных X и Y. Набор данных X имеет столбец Соединяющий ключ, который имеет повторяющиеся значения. Набор данных Y имеет столбец ключа присоединения и один дополнительный столбец. Изображения набора данных были загружены ниже. Проблема в том, что я хочу избегать декартовых произведений из-за дубликатов, присутствующих в наборе данных X. Я прикрепил изображение с результирующим набором данных ниже. Это может быть сделано вручную путем слияния вручную с использованием цикла for, но это отнимает много времени. Любой может предложить лучший метод

All DataSets Image

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Использование @Alollz setup:

df_x = pd.DataFrame({'EMM_ID': [610462, 610462, 610462, 610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18]})

Вы можете создать новый «ключ» для соединения с cumcount.

colkey = 'EMM_ID'
df_x = df_x.assign(colkey=df_x.groupby(colkey).cumcount())
df_y = df_y.assign(colkey=df_y.groupby(colkey).cumcount())

df_x[['EMM_ID','colkey']].merge(df_y, on=['EMM_ID','colkey'], how='left')

Вывод:

   EMM_ID  colkey  ID_home
0  610462       0  81000.0
1  610462       1      NaN
2  610462       2      NaN
3  610462       3      NaN
4   61000       0     18.0
5   61000       1      NaN
0 голосов
/ 11 сентября 2018

В этом случае, поскольку вам нужно всего лишь привести один столбец, .map, вероятно, больше подходит. Мы берем первое значение в каждой группе EMM_ID и отображаем только это значение. Выравнивание по индексу гарантирует, что остальные становятся NaN.

Пример данных

import pandas as pd
import numpy as np
df_x = pd.DataFrame({'EMM_ID': [610462, 610462, 610462, 610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18]})

код

df_x['ID_home'] = df_x.groupby('EMM_ID').head(1).EMM_ID.map(df_y.set_index('EMM_ID').ID_home)

Выход: df_x

   EMM_ID  ID_home
0  610462  81000.0
1  610462      NaN
2  610462      NaN
3  610462      NaN
4   61000     18.0
5   61000      NaN

Если вам нужно вывести несколько столбцов, вы можете разбить ваш DataFrame, объединить с подмножеством и затем объединить обратно в один DataFrame.

df_x = pd.DataFrame({'EMM_ID': [610462,610462,610462,610462, 61000, 61000],
                     'ID_home': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, np.NaN]})
df_y = pd.DataFrame({'EMM_ID': [610462, 61000], 'ID_home': [81000, 18], 'Val_2': ['A', 'F']})

to_merge = df_x.groupby('EMM_ID').head(1)
keep = df_x[~df_x.index.isin(to_merge.index)]

pd.concat([keep, to_merge[['EMM_ID']].merge(df_y)], sort=False).sort_index() 

Выход:

   EMM_ID  ID_home Val_2
0  610462  81000.0     A
1  610462      NaN   NaN
1   61000     18.0     F
2  610462      NaN   NaN
3  610462      NaN   NaN
5   61000      NaN   NaN
...