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