如何使用稀疏向量计算两个pandas列的每一行之间的点积

时间:2017-05-29 16:57:55

标签: python pandas scipy sparse-matrix dot-product

我有一个Pandas数据帧,其中包含两列,每列包含每行中的SciPy稀疏向量。这些向量是来自csr矩阵的行(因此它们实际上是形状为1x8500的矩阵)。

我需要创建另一个列,它应该在每一行中包含同一行前两列的向量之间的点积。

我知道如何在每行使用apply / map执行此操作,但是当我处理数百万行的数据集时需要很长时间。在整个数据框架上有更快的方法吗?

除了点积之外,我还需要计算余弦相似度,但据我所知,这可能来自点积。

更新:我无法在这里分享实际数据,但这是一个玩具示例(请注意,我现在只有结果数据框):

import pandas as pd
import numpy as np
from scipy.sparse import csr_matrix
row = np.array([0, 0, 1, 2, 2, 2])
col = np.array([0, 2, 2, 0, 1, 2])
data = np.array([1, 2, 3, 4, 5, 6])
mat = csr_matrix((data, (row, col)), shape=(3, 3))
df = pd.DataFrame({'Col_1': [mat.getrow(i) for i in range(3)],
                   'Col_2': [mat.getrow(i)*2 for i in range(3)]})

我知道我可以做这样的事情来计算点积:

df['Col_3'] = df.apply(lambda row: np.dot(row['Col_1'],
                       row['Col_2'].transpose()).toarray()[0][0], axis=1)

但是有更有效的方法来计算Col_3吗?

1 个答案:

答案 0 :(得分:0)

用你的例子

matA = mat
matB = mat*2
col3 = (matA.multiply(matB)).sum(axis=1)

[[ 10]
 [ 18]
 [154]]

for i in range(3):
    print(df['Col_1'][i].A, df['Col_2'][i].A)
[[1 0 2]] [[2 0 4]]
[[0 0 3]] [[0 0 6]]
[[4 5 6]] [[ 8 10 12]]

df['Col_1'] dtype是object,每个元素都是csr矩阵,mat.getrow(i)的结果。嵌入式标签和换行符显示有点乱。用.A产生的密集等价物更漂亮。形状是一致的,但非零术语的数量会有所不同。