Algorithm 如何计算a列中每对值之间b列中共享值的数量?

Algorithm 如何计算a列中每对值之间b列中共享值的数量?,algorithm,pandas,dataframe,graph,merge,Algorithm,Pandas,Dataframe,Graph,Merge,我有一个数据框,有两列“la”和“lb”。我想计算每对“la”值之间共享lb值的数量,条件是不在相同的“la”值之间计数,并且不无序地对一对进行两次计数,例如,不计数(1,1),如果计数(1,2),则不计数(2,1)。您可以将其视为在“la”节点之间构建一个无向的、非自循环的加权图 d = pd.DataFrame([[1, 0], [2, 0], [1, 1], [2, 1]], columns=['la', 'lb']) d Out[26]: la lb 0 1 0 1

我有一个数据框,有两列“la”和“lb”。我想计算每对“la”值之间共享lb值的数量,条件是不在相同的“la”值之间计数,并且不无序地对一对进行两次计数,例如,不计数(1,1),如果计数(1,2),则不计数(2,1)。您可以将其视为在“la”节点之间构建一个无向的、非自循环的加权图

d = pd.DataFrame([[1, 0], [2, 0], [1, 1], [2, 1]], columns=['la', 'lb'])
d
Out[26]: 
   la  lb
0   1   0
1   2   0
2   1   1
3   2   1

# The final result I want:
   la_x  la_y  count_shared_lb
0     1     2   2
1   ...   ... ...
.
.
.
目前我正在进行合并,然后是groupby和count

dd= d.merge(d, left_on='lb', right_on='lb')
dd
Out[27]: 
   la_x  lb  la_y
0     1   0     1
1     1   0     2
2     2   0     1
3     2   0     2
4     1   1     1
5     1   1     2
6     2   1     1
7     2   1     2

dd.groupby(['la_x', 'la_y'], sort=False).size().reset_index(name='count_shared_lb')
Out[30]: 
   la_x  la_y  count_shared_lb
0     1     1                2
1     1     2                2
2     2     1                2
3     2     2                2
但我被困在这里,因为我无法过滤掉不需要的行。更重要的是,数据帧太大,以至于合并会耗尽内存

所以我有两个问题:有没有一种方法可以不使用合并就完成结果?如果没有,是否有办法过滤掉不需要的行(在首选合并之前)


谢谢。

至于第二个,您可以通过删除所有具有唯一值的行来提前收缩
d
。这不会解决合并问题,但应该将初始占用空间缩小一点

counts = d.lb.value_counts()
uniq_lbs = set(counts[counts < 2].index)
d = d[~d.lb.isin(uniq_lbs)]
由于
d
中没有任何内容被更改,因此您应该能够轻松地将上述内容并行化。如果你这样做,考虑在每个过程中做计数,然后用一个和来汇总所有的<代码> Laxx,LaYy,计数< /COD>三元组。
这就是说,根据您案例的具体情况,这里最大的问题是您将执行许多最坏情况下的相似性匹配检查值,这些值没有任何共同之处。您可能想查看一些类似或的图形库,看看图形算法是否会对您有所帮助。

感谢您指出了
laux
&
lauy
的顺序,这解决了许多问题。真正的数据是字符串,所以我没有考虑它。for循环是一个很好的解决方案,我将尝试将其并行化
lb
不可能只出现一次,因此第一个技巧不会有多大帮助。你能给我更详细的关于图形工具的指导吗?我应该在这里寻找什么图形算法?我被困在pandas中,试图找到pandas做这件事的方法。是否有一个pandas特性可以替代上面的for循环?我在实际数据上实现了for循环解决方案。它工作得很好,只是与直接合并相比需要花费太长的时间。我正在将其并行化,看看这是否有帮助。谢谢
la_vals = sorted(df.la.unique())
d_list = []
for i in range(len(la_vals)-1):
    left_d = d.loc[d.la == la_vals[i], :]
    right_d = d.loc[d.la.isin(la_vals[i:]), :]
    d_list.append(left_d.\
                         merge(right_d, left_on = 'lb', right_on = 'lb').\
                         loc[:, ['la_x', 'la_y']])

final_d = pd.concat(d_list)