矢量点积

时间:2018-07-17 18:17:17

标签: python pandas vectorization dot-product

我有一个pandas数据框,其中一列在每一行中都有一个列表。我有一个单独的numpy数组query_ebd,我想在该列的每一行中加点。我想要的输出是每行一个数字,用query_ebd代表该行中列表的点积。目前,我正在做:

for row in df.itertuples():
    chat_result = query_ebd.dot(row[2])

这有效,但是很慢。我正在尝试向量化此功能,但无法正常工作。我尝试过:

chat_result = df['Embedding'].dot(query_ebd)

但是我遇到了点积形状不匹配的问题,因为它试图用query_ebd点缀该列,而不是用它来点缀每一行。我怎样才能使它点缀每一行?谢谢。

2 个答案:

答案 0 :(得分:0)

据我了解,您需要将包含列表的列乘以列长度的numpy数组。

请考虑以下示例:

df = pd.DataFrame({
    'col':[[1,2,3], [1,2]]
})
query_ebd = np.array([2,4])

让我们为query_ebd创建一个单独的列,并执行逐行列表乘法。

df['mul'] = query_ebd
chat_result = df.apply(lambda x: [y * int(x['mul']) for y in x['col']], axis=1)

输出:

0    [2, 4, 6]
1       [4, 8]
dtype: object

答案 1 :(得分:0)

IIUC

df.col.transform(lambda k: query_ebd.dot(k))

只需重新阅读您的问题,现在我就知道您想要什么。

我相信这是一个很好的解决方案,但是我欢迎批评家。

您可以定义自己的类型并覆盖__mul__,然后让numpy的内置实现为您进行矢量化

class O(object):
    def __init__(self, d):
        self.d = d
    def __mul__(self, o):
        return np.dot(self.d, o.d)

 df.col.transform(O) * O(query_ebd)

使用此示例数据,

df = pd.DataFrame({
    'col':[ ([1,2,3]), ([1,2,0])]
})

query_ebd = np.array([2,4,3])

df.col.transform(O) * O(query_ebd)

0    19
1    10

性能:

对于200万行的数据帧,

%timeit v * O(query_ebd)
4.5 s ± 230 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit s.transform(lambda k: query_ebd.dot(k))
12.4 s ± 264 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)