【问题标题】:Vectorized dot product矢量化点积
【发布时间】:2018-12-25 13:02:02
【问题描述】:

我有一个 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 点列该列,而不是用它点每一行。我怎样才能让它点每一行?谢谢。

【问题讨论】:

  • 你能显示预期的输出和最小的输入吗?

标签: python pandas vectorization dot-product


【解决方案1】:

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)

【讨论】:

  • 这不是矢量化的。
  • @juanpa.arrivillaga 现在明白这个问题..也许有解决方案
  • Tbh 不知道这种情况下是否正在进行矢量化。 IMO 这样做是有道理的,但可能拥有 O 对象会增加太多开销?
  • 好吧,dtype=object 会大大削弱矢量化的优势。它消除了参考的局部性,这可能是提高速度的主要来源。但是,循环被下推到 C 级,所以它应该更快,但不是原始数值类型所期望的 50 倍或 100 倍(或更多)速度。
  • @juanpa.arrivillaga 似乎没有解决方案,因为OP根据定义有一个可迭代的集合,所以dtype是对象,无论方法如何
【解决方案2】:

据我了解,您需要将包含列表的列乘以列长度的 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

【讨论】:

  • 我编辑了这个问题,以便更清楚地说明我想要做什么。该列的每一行都包含一个列表L_i,我想用query_ebd 来点每个列表,因此我想要的输出是每一行的点积,我想对其进行矢量化。 query_ebd 与每个列表 L_i 具有相同的长度 (256)。
  • @Luciano 如果您的 dtype=object 矢量化数据框无论如何都无济于事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多