#python #pandas
#python #pandas
Вопрос:
Я создал матрицу совместного появления следующим образом, используя pandas.
import pandas as pd
import numpy as np
lst = [
['a', 'b'],
['b', 'c', 'd', 'e', 'e'],
['a', 'd', 'e'],
['b', 'e']
]
u = (pd.get_dummies(pd.DataFrame(lst), prefix='', prefix_sep='')
.groupby(level=0, axis=1)
.sum())
v = u.T.dot(u)
v.values[(np.r_[:len(v)], ) * 2] = 0
print(v)
Результат выглядит следующим образом.
a b c d e
a 0 1 0 1 1
b 1 0 1 1 3
c 0 1 0 1 2
d 1 1 1 0 3
e 1 3 2 3 0
Я хотел бы преобразовать вышеупомянутый фрейм данных в пары (x, y). Как вы можете видеть, выходная матрица симметрична (т. е. верхняя часть по диагонали и нижняя часть по диагонали одинаковы). Поэтому я рад получить пары (x, y) только из одной их части (например, используя только верхнюю часть).
Итак, в приведенной выше матрице выводом должны быть (т.Е. (x, y) пары, значение которых больше нуля >0
);
[('a','b'), ('a', 'd'), ('a','e'), ('b', 'c'), ('b', 'd'), ('b', 'e'),
('c', 'd'), ('c', 'e'), ('d', 'e')]
Возможно ли выполнить это в pandas?
Я рад предоставить более подробную информацию, если это необходимо.
Ответ №1:
Вы можете попробовать np.where:
arr = np.where(v>=1)
corrs = [(v.index[x], v.columns[y]) for x, y in zip(*arr)]
corrs
[('a', 'b'),
('a', 'd'),
('a', 'e'),
('b', 'a'),
('b', 'c'),
('b', 'd'),
('b', 'e'),
('c', 'b'),
('c', 'd'),
('c', 'e'),
('d', 'a'),
('d', 'b'),
('d', 'c'),
('d', 'e'),
('e', 'a'),
('e', 'b'),
('e', 'c'),
('e', 'd')]
Затем вы можете отфильтровать список:
final_arr = []
for x, y in corrs:
if (y,x) not in final_arr:
final_arr.append((x,y))
final_arr
[('a', 'b'),
('a', 'd'),
('a', 'e'),
('b', 'c'),
('b', 'd'),
('b', 'e'),
('c', 'd'),
('c', 'e'),
('d', 'e')]
Ответ №2:
Это также работает:
pd.DataFrame(np.argwhere(v.values>0)).replace({0:'a', 1:'b', 2:'c', 3:'d', 4:'e'}).values
Ответ №3:
Используйте numpy.triu
для матрицы верхнего треугольника, получайте индексы через numpy.nonzero
или numpy.where
и последние zip
значения индекса и столбцов, созданных путем индексирования:
i, c = np.nonzero(np.triu(v.values))
#alternative
#i, c = np.where(np.triu(v.values))
L = list(zip(v.index[i], v.columns[c]))
print (L)
[('a', 'b'),
('a', 'd'),
('a', 'e'),
('b', 'c'),
('b', 'd'),
('b', 'e'),
('c', 'd'),
('c', 'e'),
('d', 'e')]