Как объединить два фрейма данных, где идентификаторы не совпадают, и создать новый столбец для представления того, откуда был взят идентификатор фрейма данных? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть два кадра данных, как это

df1:

id    column1    column2 
1      30          90
2      1            2

df2:

id    column1    column2 
1      30          90
3      1            2

Я хочу создать логику, которая объединяет эти два кадра данных, где идентификаторы делаютне совпадают (имена столбцов совпадают), а затем я хочу создать новый столбец, в котором будет указано, с какого кадра данных был получен идентификатор.Как бы я это сделал?

Окончательное объединение df:

id    column1    column2    df_name
2      30          90         df1
3      1            2         df2

edit:

Может ли окончательное df извлечь все столбцы из обоих кадров данных?

 id    column1.df1    column2.df1   column1.df2    column2.df2     df_name
    2      30          90                 30            90           df1
    3      1            2                  1             2           df2

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Давайте сделаем с merge

df=df1.merge(df2,indicator = True,how='outer').loc[lambda x : x['_merge'].ne('both')]
df['df_name']=df['_merge'].map({'left_only':'df1','right_only':'df2'})
df
Out[328]: 
   id  column1  column2      _merge df_name
1   2        1        2   left_only     df1
2   3        1        2  right_only     df2
0 голосов
/ 29 ноября 2018

Первый concat DataFrames вместе:

df = (pd.concat([df1, df2],  keys=('df1','df2'))
        .rename_axis(('df_name','idx'))
        .reset_index(level=1, drop=True)
        .reset_index())

print (df)
  df_name  id  column1  column2
0     df1   1       30       90
1     df1   2        1        2
2     df2   1       30       90
3     df2   3        1        2

Затем получить все то же самое id:

a = df1.merge(df2, on='id')['id']

И последний фильтр по isin:

df = df[~df['id'].isin(a)]
print (df)
  df_name  id  column1  column2
1     df1   2        1        2
3     df2   3        1        2

РЕДАКТИРОВАТЬ:

Аналогичное решение, как @WB, только добавленный параметр id и suffixes:

df = (df1.merge(df2,indicator=True,how='outer', on='id', suffixes=('_df1','_df2'))
         .query("_merge != 'both'"))
df['_merge'] = df['_merge'].map({'left_only':'df1','right_only':'df2'})

print (df)
   id  column1_df1  column2_df1  column1_df2  column2_df2 _merge
1   2          1.0          2.0          NaN          NaN    df1
2   3          NaN          NaN          1.0          2.0    df2

Еслихотите, чтобы все строки, а также строки с одинаковыми id:

df['_merge'] = df['_merge'].map({'left_only':'df1','right_only':'df2', 'both':'df1+df2'})

print (df)
   id  column1_df1  column2_df1  column1_df2  column2_df2   _merge
0   1         30.0         90.0         30.0         90.0  df1+df2
1   2          1.0          2.0          NaN          NaN      df1
2   3          NaN          NaN          1.0          2.0      df2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...