Numpy:填充共现矩阵的最快方法

2024-09-28 16:59:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个很长的索引元组列表(大量重复),以及一个n×n索引矩阵。每个元组表示一个共现

例如:

a = np.zeros(shape=(indexCount,indexCount))

我试过这个:

for i1,i2 in coocPairs:  #for instance (2374, 22003)
   a[i1][i2}+=1  #takes way too long

或:

np.put(a,coocPairs,1) #which obviously does not increment

或者:

np.add(a,coocPairs,1) #which takes even longer.

在一个理想的世界中,会有一个函数接受我的元组列表,并用它构建一个共现矩阵,但唉(doc.不是很有帮助)。我认为解决方案可以更多地放在代码的python方面,但我已经没有想法了。欢迎任何帮助。谢谢你抽出时间


Tags: instanceinwhich列表fornpzeros矩阵
2条回答

您可以使用np.add.at

np.add.at(a,tuple(coocPairs.T),1)

如果速度不够快,则会有更快但更不直接的基于np.bincount的解决方案。这些依赖于使用np.ravel_multi_index的平坦索引

您可以使用collections.Counter获取实际出现在矩阵中的值。这是因为元组是可散列的。任务变得非常简单:

counts = collections.Counter(coocPairs)
ind = np.array(list(counts.keys())).T
a[ind[0], ind[1]] = list(counts.values())

通常,np.uniquereturn_counts=TrueCounter的代名词。在这种情况下,有必要指定轴,并记住它将是较慢的解决方案之一:

ind, count = np.unique(coocPairs, return_counts=True, axis=0)
a[ind.T[0], ind.T[1]] = count

相反,您可以将线对转换为展开矩阵中的线性索引:

ind = np.ravel_multi_index(tuple(np.array(coocPairs).T), a.shape)

现在你可以做了

ind, count = np.unique(ind, return_counts=True)
a.ravel()[ind] = count

或者,您可以使用^{}来加快计数,或者使用np.add.at来避免预先计数。带有raveled索引的bincount解决方案省去了预分配a的麻烦:

ind = np.ravel_multi_index(tuple(np.array(coocPairs).T), (n, n))
a = np.bincount(ind, minlength=n * n).reahape(n, n)

相关问题 更多 >