为两个列表创建 'correlation matrix' 以检查值是否有共同点

Create 'correlation matrix' for two lists to check if the values have something in common

有人可以帮我解决以下问题吗?

我有一个包含两列的数据框:产品和带有 n 种产品的网上商店 (n x 2)。现在我想获得一个二进制 (n x n) 矩阵,其中所有产品都列为索引,所有产品都列为列名。然后每个单元格应包含 1 或 0,表示索引中的产品和列名称是否来自同一网店。

以下代码返回我想要实现的目标。

dist = np.empty((len(df_title), len(df_title)), int)

for i in range(0,len(df_title)):
    for j in range(0,len(df_title)):
            boolean = df_title.values[i][1] == df_title.values[j][1]
            dist[i][j] = boolean  
df = pd.DataFrame(dist)

但是,对于 n = 1624,此代码已经花费了相当多的时间。因此我想知道是否有人会想到更快的算法。

谢谢!

您似乎只对每一列位置 1 处的元素感兴趣,因此创建一个临时变量以便于查找可能会有所帮助:

lookup = df_title.values[:, 1]

此外,由于您想将结果矩阵解释为 bool-矩阵,您可能应该指定 dtype=bool(每个字段 1 个字节)而不是 dtype=int(每个字段 8 个字节), 这也减少了 8 的内存消耗。

dist = np.empty((len(df_title), len(df_title)), dtype=bool)

你的矩阵无论如何都会沿对角线对称,所以你只需要计算矩阵的“一半”,如果 i == j 我们知道矩阵中的相应字段应该是 True .

lookup = df_title.values[:, 1]
dist = np.empty((len(df_title), len(df_title)), dtype=bool)

for i in range(len(df_title)):
    for j in range(len(df_title)):
        if i == j:
            # diagonal
            dist[i, j] = True
        else:
            # symmetric along diagonal
            dist[i, j] = dist[j, i] = lookup[i] == lookup[j]

同样使用 numpy-broadcasting 你实际上可以将所有这些转换成一行代码,这比双 for 循环解决方案快几个数量级:

lookup = df_title.values[:, 1]
dist = lookup[None, :] == lookup[:, None]