Сопоставление нескольких таблиц
Имеется 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 шт):
Зачем использовать циклы, если можно воспользоваться векторизацией? В противном случае теряется весь смысл 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