Есть 2 фрейма данных и один иерархический индекс (pandas multiIndex). Фрейм данных A имеет список идентификаторов и имен. Фрейм данных B содержит список комбинаций имен и оценку сходства.
Я хочу, основываясь на мультииндексе, взять значения из Dataframe A и проверить, существует ли комбинация в DataFrame B. Если да, я хочу вывести в мой Multindex dataframe оценку сходства, в противном случае просто 0.
DataFrame A (исходный DataFrame)
test= pd.DataFrame({'row':['a','b','c','d'],'col_A' : ["Alexis","Alexi","Peter","Pete"]})
test = test.set_index('row');test
Out:
row col_A
a Alexis
b Alexi
c Peter
d Pete
DataFrame B (сходство имен)
names = pd.DataFrame({'A' : ["Alexis","Alexi","Peter","Pete"]
,'B' : ["Alexi","Alexis","Pete","Peter"]
, "similarity" : [0.9,0.9,0.8,0.8]})
Out:
A B similarity
0 Alexis Alexi 0.9
1 Alexi Alexis 0.9
2 Peter Pete 0.8
3 Pete Peter 0.8
Мультииндекс
# Creating a Pandas MultiIndex
arrays = [['a', 'a', 'a', 'b', 'b', 'c'],
['b', 'c', 'd', 'c', 'd', 'd']]
tuples = list(zip(*arrays))
indexy = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
для итерации по индексу я использую приведенную ниже функцию, однако я не уверен, как ее настроить, чтобы получить оценку сходства, если она существует, или 0, когда ее нет.
a = pd.DataFrame((test.reindex(indexy.get_level_values(0)).values (?) test.reindex(indexy.get_level_values(1))).values,index=indexy,columns=test.columns)
Где я хочу выглядеть так:
row similarity
first second
a b 0.9
c 0
d 0
b c 0
d 0
c d 0.8
Я создаю 3 мультииндексных фрейма данных, которые я объединю позже. Первый datafrme включает сравнение числовых данных (так что разница между сущностями a, bc, d, ...) Второй включает категориальное сравнение, совпадение не совпадает и последнее, где я хочу включить сходство строк на основе значений stting . Позже я буду использовать этот объединенный набор данных в качестве входных данных для алгоритма. Отвечает ли это на ваш вопрос?
Да, чтобы получить a
, мне было интересно, почему вы использовали мультииндексный df.
Вроде я использую иерархическую индексацию, которая является разделом MultiIndex приведенного выше кода. Однако я не уверен, как совместить это с vlookup в таблице оценки сходства. a - это не полностью завершенная команда. Это именно то, о чем я прошу. Как мне правильно закодировать a, чтобы получить желаемый результат.
Итак, если вы не слишком увлечены мультииндексом, вот один из способов получить ваши данные, как вы ожидаете:
import pandas as pd
test= pd.DataFrame({'row':['a','b','c','d'],'col_A' : ["Alexis","Alexi","Peter","Pete"]})
names = pd.DataFrame({'A' : ["Alexis","Alexi","Peter","Pete"],
'B' : ["Alexi","Alexis","Pete","Peter"],
"similarity" : [0.9,0.9,0.8,0.8]})
Заметьте, я не set_index
test
, но вы можете это сделать, это немного изменит следующее (см. Комментарии). Вы можете создать фрейм данных a
, например:
import itertools
a = pd.DataFrame([p for p in itertools.combinations(test['col_A'], 2)],columns =['A','B'],
index=['%s,%s'%p for p in itertools.combinations(test['row'], r=2)])
# here if you did set_index your test, then replace
# index=['%s,%s'%p for p in itertools.combinations(test['row'], r=2)] by
# index=['%s,%s'%p for p in itertools.combinations(test.index, r=2)]
А это выглядит так:
A B
a,b Alexis Alexi
a,c Alexis Peter
a,d Alexis Pete
b,c Alexi Peter
b,d Alexi Pete
c,d Peter Pete
Затем вы можете использовать reset_index
(чтобы получить текущий индекс в качестве столбца, но это зависит от того, что именно вы хотите) merge
с names
в столбцах A и B, заполните nan
значением 0, отбросьте два столбца A и B и переименуйте (при необходимости) :
a = a.reset_index().merge(names, how = 'left', on = ['A','B']).fillna(0).\
drop(labels = ['A','B'], axis=1).rename(columns = {'index':'row', 'similarity':'col_A'})
Дай мне знать, сможешь ли ты делать то, что хочешь, после
Обновлено: с новым результатом, который вы ищете, вы можете:
a = pd.DataFrame([p for p in itertools.combinations(test['col_A'], 2)],columns =['A','B'],
index=pd.MultiIndex.from_tuples([p for p in itertools.combinations(test.index, r=2)], names=['first', 'second']))
Примечание: itertools
генерирует кортежи, которые используются в pd.MultiIndex.from_tuples
для определения вашего мультииндексного DF.
Теперь вы можете merge
(чтобы сохранить мультииндекс, вам нужно reset_index
до и set_index
после:
a = a.reset_index().merge(names, how = 'left', on = ['A','B']).fillna(0).\
drop(labels = ['A','B'], axis=1).set_index(['first', 'second'])
Привет, Бен! Это здорово, но мне нужно, чтобы фрейм данных был с иерархической индексацией. Itertools не удерживают уровень. Можно ли сделать то же самое с использованием иерархического индекса?
Я могу заполнить иерархическую таблицу следующим образом: df = pd.DataFrame (index = indexy, columns = ["подобие"]) df ["A"] = test.reindex (indexy.get_level_values (0)). Values df [" B "] = test.reindex (indexy.get_level_values (1)). Values Но как я могу объединить их на основе значений?
@ A.Papa Я думаю, что мой EDIT должен делать то, что вы ищете, но если нет, я не уверен, что понимаю, что вы хотите и почему вы хотите использовать test.reindex(indexy.get_level_values(0)).values
. Надеюсь, это все равно поможет :)
Я обновил свой вопрос. В конце мне нужен иерархический фрейм данных. Это означает двухуровневые индексы. Мне не обязательно использовать этот test.reindex(indexy.get_level_values(0)).values
только для того, чтобы получить фрейм данных на основе иерархических индексов index.
@ A.Papa, если вы попробуете мой вчерашний EDIT, у вас будет иерархический DF
Вот и получилось! Спасибо за дальнейшие объяснения!
Вот еще один способ сделать это, используя мультииндексы, merge
и map
:
from itertools import combinations
a = pd.DataFrame(index = pd.MultiIndex.from_tuples(list(combinations(test.col_A,2))))
a = a.merge(names, left_index=True, right_on=['A','B'],how='left').fillna(0)
testmap = test.reset_index().set_index('col_A').squeeze()
a['A'] = a.A.map(testmap)
a['B'] = a.B.map(testmap)
a = a.set_index(['A','B'])
a
Выход:
similarity
A B
a b 0.9
c 0.0
d 0.0
b c 0.0
d 0.0
c d 0.8
Вам нужно создать мультииндексный DF по другой причине, чтобы получить ожидаемый результат?