Вычислить пересечение списков для каждой пары значений в столбце - PullRequest
0 голосов
/ 09 февраля 2019

Если у меня есть набор данных, который имеет 2 столбца user_id и их интересы, и я хочу найти пользователей, имеющих общие интересы, как я могу это сделать?Например, я возьму первого пользователя и его интересы и сопоставлю его с общими интересами всех остальных пользователей по отдельности, затем я возьму второго пользователя и сравню его интересы с интересами всех других пользователей и т. Д. ...

Мои данные выглядят так:

userid   interest
 1       [A, B]
 2       [A, C, B]
 3       [B, D]

Я не уверен, как это сделать -

for i in range(0,3):
  for j in range(i+1, 3):
    print((df['interest'].loc[i]).intersection(df['interest'].loc[j]))

Мой вывод должен быть -

userid    relativeid  common interest
  1          2           [A, B]
  1          3           [B]
  2          3           [B]

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Используйте словарь для поиска.Затем вы можете найти комбинации «userid», используя itertools.combinations, а затем просто выполнить пересечение набора для каждой пары «userid» списка.

import itertools

m = df.set_index('userid')['interest'].map(set).to_dict()
m 
# {1: {'A', 'B'}, 2: {'A', 'B', 'C'}, 3: {'B', 'D'}}

out = pd.DataFrame(
    itertools.combinations(df.userid, 2), columns=['userid', 'relativeid'])
out['common_interest'] = [list(m[x] & m[y]) for x, y in out.values]
out

   userid  relativeid common_interest
0       1           2          [B, A]
1       1           3             [B]
2       2           3             [B]
0 голосов
/ 09 февраля 2019

Вот как бы я решил это, возможно, у кого-то есть более изумительный способ pandas.

from itertools import combinations

cs = combinations(df.userid.values, 2)
output = pd.DataFrame(list(cs), columns=['userid', 'relativeid'])

print(output)

   userid  relativeid
0       1           2
1       1           3
2       2           3


def intersect(row):
    p1 = df.loc[df.userid == row['userid'], 'interest'].values[0]
    p2 = df.loc[df.userid == row['relativeid'], 'interest'].values[0]
    return list(set(p1).intersection(set(p2)))

output.assign(common_interest=output.apply(intersect, axis=1))

   userid  relativeid common_interest
0       1           2          [B, A]
1       1           3             [B]
2       2           3             [B]
...