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

标签 algorithm pandas dataframe graph merge

我有一个包含 2 列“la”和“lb”的数据框。我想计算每对“la”值之间的共享 lb 值的数量,条件不在相同的“la”值之间计算并且不计算一对无序两次,例如,不计算 (1, 1),不计算 ( 2, 1) 如果计算 (1, 2)。您可以将其视为在“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 和计数。

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

但我被困在这里,因为我无法过滤掉不需要的行。更重要的是,数据框太大以至于合并耗尽了内存。

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

谢谢。

最佳答案

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

counts = d.lb.value_counts()
uniq_lbs = set(counts[counts < 2].index)
d = d[~d.lb.isin(uniq_lbs)]

至于一个,最简单的答案是只删除 la_x >= la_y 的所有行,因为这应该涵盖所有冗余计数。也就是说,如果您改为通过 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)

您应该能够毫不费力地将上述内容并行化,因为 d 中的任何内容都没有被更改。如果这样做,请考虑在每个进程中进行计数,然后在最后使用总和聚合所有 la_x, la_y, count 三元组。

也就是说,根据您案例的具体情况,这里最大的问题是您将进行很多最坏情况下的相似性匹配——检查没有任何共同点的值。您可能想看看一些图形库,例如 networkxigraph看看图形算法是否对您有所帮助。

关于algorithm - 如何计算a列中每对值之间b列中共享值的数量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42777548/

相关文章:

algorithm - 将六个平面形状变成一个立方体

python - pandas - 从一组中取 N 个最后值

algorithm - interview Q :Given an input array of size unknown with all 1's in the beginning and 0' s in the end. 查找数组中从0开始的索引

python - 根据时间戳中的月份过滤数据框

python - 数据框 set_index 未设置

python - 一次将名称以字符串 `abc_` 开头的多个 bool 列转换为整数 dtype

java - 查找与给定数字非常接近的数字

python - 根据其他列值重命名列

python - pandas DataFrame 按多个列值 reshape

r - 带有嵌套 if/else 的 For 循环给出不完整的输出