pandas 如何优化这段 numpy 代码以使其更快?

7lrncoxx  于 2023-02-27  发布在  其他
关注(0)|答案(2)|浏览(492)

这段代码按预期工作,并计算两个嵌入之间的cosign距离。但它需要很多时间。我有成千上万的记录要检查,我正在寻找一种方法,使它更快。

import pandas as pd
import numpy as np
from numpy import dot
from numpy.linalg import norm

import ast

df = pd.read_csv("https://testme162.s3.amazonaws.com/cosign_dist.csv")

for k, i in enumerate(df["embeddings"]):
    df["dist" + str(k)] = df.embeddings.apply(
        lambda x: dot(ast.literal_eval(x), ast.literal_eval(i))
        / (norm(ast.literal_eval(x)) * norm(ast.literal_eval(i)))
    )
lstz6jyr

lstz6jyr1#

    • 优化方式**:

不是在循环中多次应用ast.literal_eval,而是使用converters选项一次加载具有所需结构的输入csv文件,以便使用numpy.fromstring例程将所有'embeddings'列数组字符串表示转换为"实数"数组。

df = pd.read_csv("https://testme162.s3.amazonaws.com/cosign_dist.csv", 
                 delimiter=',', usecols=["embeddings"], quotechar='"',
                 converters = {'embeddings': lambda s: np.fromstring(s[1:-1], sep=',')})

在上面的过程中,在我的测量中,numpy.fromstringconverters = {'embeddings': ast.literal_eval}6倍,尽管后者反过来比您最初的方法快。
然后,为避免使用新的dist<num>列插入多个 Dataframe ,请将for循环替换为pd.concat

df = pd.concat([df] + [df.embeddings.apply(
                        lambda x: np.dot(x, arr)
                                  / (np.linalg.norm(x) * np.linalg.norm(arr))
                        ).rename(f'dist{i}')
                        for i, arr in enumerate(df["embeddings"])], axis=1)

最终结果(前3条记录的片段):
一个二个一个一个

4xrmg8kj

4xrmg8kj2#

我试图给出一个解决方案,为数据embeddings创建一个数据库,然后用库scipy.spatial.distance计算距离,df3是您预期的结果。

import pandas as pd
import numpy as np
from scipy.spatial import distance
from numpy.linalg import norm
import ast
import time 

start = time.perf_counter()

df = pd.read_csv("https://testme162.s3.amazonaws.com/cosign_dist.csv")

num_colums = len(ast.literal_eval(df["embeddings"][0]))
num_lines = len(df["embeddings"])
data_base_embeddings =np.zeros((num_lines, num_colums))

colums_list = []

for k, i in enumerate(df["embeddings"]):
    embeddings_temp = np.array(ast.literal_eval(i))
    data_base_embeddings[k, :] = embeddings_temp
    colums_list.append("dist" + str(k))
    

dist_matix = distance.cdist(data_base_embeddings, data_base_embeddings, lambda u, v: np.dot(u,v) / (norm(u)*norm(v)))

df2 = pd.DataFrame(data=dist_matix, columns=colums_list)

df3 = df.join(df2)

end = time.perf_counter()

print("Running time: ", str(end - start), "s")

它为您提供了包括加载数据在内的运行时间:
运行时间:2.0602212000012514秒
不包括加载数据:
运行时间:0.7129389000001538秒

相关问题