在pandas数据框中计数,对于A的每个a_i,a_j,计算a_i和a_j与相同的b列出的次数

问题描述 投票:0回答:1

我有一个大数据框(1M 行),有两列 A、B。

对于 A 的每一对 a_i, a_j,我想知道 B 中 b 的数量,使得同时存在行 a_i,b 和 a_j,b

例如:

A B
a1 b1
a2 b1
a3 b2
a1 b3
a3 b3
a4 b3
a2 b4
a1 b5
a3 b5
a3 b6
a4 b6

这里我有一对 a1,a3 共享 b3 和 b5

结果将是以下矩阵(根据定义,该矩阵是对称的):

a1 a2 a3 a4
a1 xx 1 2 1
a2 1 xx 0 0
a3 2 0 xx 2
a4 1 0 2 xx

我认为以下方法会起作用:

df = pd.DataFrame({'A' : ['a1','a2','a3','a1','a3','a4','a2','a1','a3','a3','a4'],
 'B':['b1','b1','b2','b3','b3','b3','b4','b5','b5','b6','b6']})

df_dum = df.set_index('A')['B'].str.get_dummies().reset_index()
df_dum = df_dum.groupby('A').sum()
np_cnt = df_dum.to_numpy()
np_mul = np.matmul(np_cnt,np_cnt.T)

但是它需要太多的时间和内存,并且不能与我的 1M 行一起运行。此外,对角线是计算出来的,而我不需要它,而且我认为通过虚拟值并不是一个好主意,特别是因为生成的二进制文件非常稀疏。

但我没有更多的想法了...

你有什么建议?

编辑:

为了了解更多背景信息,我们假设 A 是学生,B 是课程。 最后我想知道对于任何两个学生来说,他们总共有多少课程。对于每对至少共享一门课程的学生来说也是如此。 如果这更有意义:)

pandas numpy count binary-matrix
1个回答
0
投票

尝试使用

itertools.permutations

import itertools

sets = df.groupby('B')['A'].apply(lambda x : list(itertools.permutations(x, 2))).explode().tolist()
sets = pd.DataFrame(sets)

index = df["A"].unique()
output = pd.crosstab(sets[0],sets[1],rownames=[None],colnames=[None]).reindex(index).reindex(index, axis=1)

>>> output
    a1  a2  a3  a4
a1   0   1   2   1
a2   1   0   0   0
a3   2   0   0   2
a4   1   0   2   0
© www.soinside.com 2019 - 2024. All rights reserved.