我有一个2D numpy数组,有数十万行和一千个左右的列(假设它是N×P数组,N = 200,000,P = 1000) . 这里的目标是计算每对行向量之间相同元素的数量,理想情况下使用numpy数组魔术,不需要我执行199,999 * 100,000个这样的对的循环 . 由于存储200,000×200,000阵列可能不可行,因此输出可能是Nx3稀疏坐标格式,例如,如果输入的形式如下:

5 12 14 200   0 45223
7 12 14   0 200 60000
7  6 23   0   0 45223
5  6 14 200   0 45223

得到的(密集的)NxN矩阵M将是(不关心对角线元素):

0 2 2 4
2 0 2 1
2 2 0 3
4 1 3 0

假设基于0的索引,Mij包含初始行i和初始行j之间的相同元素的数量 . 因此,预期的稀疏输出当量将是:

0 1 2
0 2 2
0 3 4
1 2 2 
1 3 1
2 3 3

一种天真的,非常低效的实现方法是:

import itertools
import numpy as np

def pairwise_identical_elements(small_matrix):
    n, p = small_matrix.shape
    coordinates = itertools.combinations(range(n), 2)
    sparse_coordinate_matrix = []
    for row1, row2 in itertools.combinations(small_matrix, 2):
        idx1, idx2 = next(coordinates)
        count = p - np.count_nonzero(row1 - row2)
        sparse_coordinate_matrix.append([idx1, idx2, count])
    return sparse_coordinate_matrix

我已经研究了距离度量实现,例如scipy和sklearn中的Jaccard相似性,但它们都假设输入行向量必须是二进制的 . 我还尝试添加第三个维度以使条目成为二进制(例如,条目'9'变为零的向量,在第9个位置具有1)但是存在明显的内存问题(条目'45223'将需要第三维伸展那么多元素) .

是否有一种高效,可扩展和/或pythonic解决方案使用numpy或scipy以我错过的方式?

Edit :在进一步研究scipy之后,我发现了一些与我正在尝试的东西非常匹配的东西,即带有汉明度量的scipy.sparse.distance.pdist . 然而,它以'condensed'形式返回输出,并且由于我们试图避免转换为完全密集阵列以节省内存,因此问题可能变成:如何将压缩距离矩阵转换为稀疏矩阵?