Сопоставление нескольких таблиц

Имеется 2 таблицы с разным количеством строк и столбцов. Таблицы объединяет одно поле: name

Нужно сделать так, чтобы одна таблица взяла индексы из другой по полю name

tab 1
id | name    | value1 | value2| value3| ....
0  | name1   | some1  | some2 | some3 | ....
1  | name2   | some1  | some2 | some3 | ....
...
500| name500 | some   | some  | some  | ....

tab 2

id | value| value | value | name    | ...
0  | some | some  | some  | name500 | ...
1  | some | some  | some  | name2   | ...
...
900|some  | some  | some  | name1   | ...

Мне нужно добавить индексы из второй таблицы в последний столбец первой

tab 1 upgrade

tab 1
id | name    | value1 | value2| value3| .... | id_from_tab2
0  | name1   | some1  | some2 | some3 | .... | 900
1  | name2   | some1  | some2 | some3 | .... | 1
...
500| name500 | some   | some  | some  | .... | 0

Обе таблицы импортятся из csv Пробую что-то вроде:

import pandas as pd

tab1 = pd.read_csv( PATH, sep=';')
tab2 = pd.read_csv( PATH, sep=';')

for i in tab1['name']:
    if i in tab2['name']:
        tab1['id_from_tab2'] = tab2['id']

   ...и т.д.

Подобным образом это не работает. Явно я не понимаю каких-то базовых вещей и нужно углубляться, тем не менее хотел бы понять как решается именно эта задача и буду рад помощи.


Ответы (1 шт):

Автор решения: strawdog

Зачем использовать циклы, если можно воспользоваться векторизацией? В противном случае теряется весь смысл pandas.

Исходные данные:

import pandas as pd

a = {'name':['name1', 'name2', 'name3'], 'value1':['f','o','o']}
b = {'name':['name3', 'name5', 'name2'], 'value1':['b','a','r']}
df1 = pd.DataFrame(a)
df2 = pd.DataFrame(b)
print(df1)
print(df2)

То есть:

    name value1
0  name1      f
1  name2      o
2  name3      o
    name value1
0  name3      b
1  name5      a
2  name2      r

Можно сделать так:

1.

df1['new'] = df1['name'].apply(lambda x: df2[df2['name']==x].index[0])
df1

Результат:

    name    value1  new
0   name1   f       1
1   name2   o       2
2   name3   o       0

Но! если у вас будут несоответствия в значениях в колонке names, этот способ не сработает.

Поэтому вернее будет делать так:

df2['new'] = df2.index.astype('object')
res = df1.set_index('name').join(df2.set_index('name'), rsuffix='_r').reset_index()
res

Результат:

    name value1 value1_r new
0  name1      f        a   1
1  name2      o        r   2
2  name3      o        b   0

В данном случае, даже если у вас будет на соответствие в колонках обоих фреймов, отсутствeеющие значения будут переданы как Nan.

Возможно (надеюсь), коллеги оптимизируют мой join - у меня мало времени сейчас

UPDATE (as per MaxU):

как посоветовал MaxU, проще и эффективнее будет сделать так:

df2['new'] = df2.index.astype('object')
df1 = df1.merge(df2, on='name')

В этом случае df1 будет:

    name value1_x value1_y idx
0  name1        f        a   1
1  name2        o        r   2
2  name3        o        b   0
→ Ссылка