从python中的列表列表构造共现矩阵

时间:2018-12-19 11:46:39

标签: python pandas dataframe

假设我们有由一些值组成的n个列表。

one_user = User.select().where(User.name == some_value).dicts()[0]

这里n = 4。

这将产生一个如下图所示的数据框

['a', 'b']
['b', 'c', 'd', 'e']
['a', 'd', 'e']
['b', 'e']

2 个答案:

答案 0 :(得分:2)

lst = [
    ['a', 'b'],
    ['b', 'c', 'd', 'e'],
    ['a', 'd'],
    ['b', 'e']
]

您可以使用get_dummies + groupbysum,然后再使用dot产品:

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  0
b  1  0  1  1  2
c  0  1  0  1  1
d  1  1  1  0  1
e  0  2  1  1  0

详细信息
首先,加载您的数据框。

pd.DataFrame(lst)

   0  1     2     3
0  a  b  None  None
1  b  c     d     e
2  a  d  None  None
3  b  e  None  None

接下来,为这些值生成一个热编码。这是计算共现计数的第一步。

pd.get_dummies(_, prefix='', prefix_sep='')

   a  b  b  c  d  e  d  e
0  1  0  1  0  0  0  0  0
1  0  1  0  1  0  0  1  1
2  1  0  0  0  1  0  0  0
3  0  1  0  0  0  1  0  0

接下来,按标题组合列并对其进行计数。

_.groupby(level=0, axis=1).sum()

   a  b  c  d  e
0  1  1  0  0  0
1  0  1  1  1  1
2  1  0  0  1  0
3  0  1  0  0  1

u = _

接下来,使用点积计算交叉表。

u.T.dot(u)

   a  b  c  d  e
a  2  1  0  1  0
b  1  3  1  1  2
c  0  1  1  1  1
d  1  1  1  2  1
e  0  2  1  1  2

v = _

最后,将对角线设置为0。

v.values[(np.r_[:len(v)], ) * 2] = 0
v

   a  b  c  d  e
a  0  1  0  1  0
b  1  0  1  1  2
c  0  1  0  1  1
d  1  1  1  0  1
e  0  2  1  1  0

答案 1 :(得分:1)

这是一种方法:

l1=['a', 'b']
l2=['b', 'c', 'd', 'e']
l3=['a', 'd', 'e']
l4=['b', 'e']

从列表中获取嵌套列表:

l = [i for i in [l1,l2,l3,l4]]

使用itertools.combinations获取每个列表中的所有组合:

c = [list(itertools.combinations(i,2)) for i in l]
#[[('a', 'b')],
#[('b', 'c'), ('b', 'd'), ('b', 'e'), ('c', 'd'), ('c', 'e'), ('d', 'e')],
#[('a', 'd'), ('a', 'e'), ('d', 'e')],
#[('b', 'e')]]

展平嵌套列表。请注意,每个元素都使用chain.from_iterable((i, i[::-1])以原始和相反的顺序添加。

a = list(chain.from_iterable((i, i[::-1]) for c_ in c for i in c_))

使用pivot_table并通过size进行汇总,以根据结果生成同现矩阵

df = pd.DataFrame(a)
pd.pivot_table(df, index=0, columns=1, aggfunc='size', fill_value=0)

1    a    b    c    d    e
0                         
a  0.0  1.0  0.0  1.0  1.0
b  1.0  0.0  1.0  1.0  2.0
c  0.0  1.0  0.0  1.0  1.0
d  1.0  1.0  1.0  0.0  2.0
e  1.0  2.0  1.0  2.0  0.0