Союз двух панд DataFrames

Скажем, у меня есть два фрейма данных:

дф1:

  A
0 a
1 b

дф2:

  A
0 a
1 c

Я хочу, чтобы результатом был союз двух кадров с дополнительная колонка, показывающим кадр исходных данных, к которому принадлежит строка. В случае дубликатов дубликаты должны быть удалены, а в соответствующем дополнительном столбце должны отображаться оба источника:

  A  B
0 a  df1, df2
1 b  df1
2 c  df2

Я могу получить объединенный фрейм данных (df3) без дубликатов следующим образом:

import pandas as pd
df3=pd.concat([df1,df2],ignore_index=True).drop_duplicates().reset_index(drop=True)

Я не могу придумать/найти способ контролировать, какой элемент куда идет. Как я могу добавить дополнительный столбец?

Большое спасибо за любые советы.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
11
0
8 440
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Объедините с аргументом indicator и переназначьте результат:

m = {'left_only': 'df1', 'right_only': 'df2', 'both': 'df1, df2'}

result = df1.merge(df2, on=['A'], how='outer', indicator='B')
result['B'] = result['B'].map(m)

result
   A         B
0  a  df1, df2
1  b       df1
2  c       df2

Отлично! Не могли бы вы добавить, как сделать то же самое для пересечения? внешний->внутренний?

Leon Rai 22.01.2019 21:28

@ LeonRai df1.merge(df2, on=['A'], how='inner').assign(B='df1, df2') (поскольку пересечение подразумевает членство в обоих)

cs95 22.01.2019 21:29

Понятно! Спасибо за подробный ответ!

Leon Rai 22.01.2019 21:30

Используйте команду ниже:

df3 = pd.concat([df1.assign(source='df1'), df2.assign(source='df2')]) \
    .groupby('A') \
    .aggregate(list) \
    .reset_index()

Результат будет:

   A      source
0  a  [df1, df2]
1  b       [df1]
2  c       [df2]

assign добавит столбец с именем source со значениями df1 и df2 в ваши кадры данных. Команда groupby группирует строки с одинаковым значением A в одну строку. Команда aggregate описывает, как агрегировать другие столбцы (source) для каждой группы строк с одним и тем же A. Я использовал агрегатную функцию list, чтобы столбец source был списком значений с одним и тем же A.

Мы используем внешнее соединение, чтобы решить эту проблему -

df1 = pd.DataFrame({'A':['a','b']})
df2 = pd.DataFrame({'A':['a','c']})
df1['col1']='df1'
df2['col2']='df2'
df=pd.merge(df1, df2, on=['A'], how = "outer").fillna('')
df['B']=df['col1']+','+df['col2']
df['B'] = df['B'].str.strip(',')
df=df[['A','B']]
df

   A        B
0  a  df1,df2
1  b      df1
2  c      df2

приятно Леон :)

cph_sto 22.01.2019 21:38

Другие вопросы по теме