无法理解为什么在进一步处理 col 之前将 eval 作为参数传入,即 df.<COL_NAME>.apply(eval).apply(np.array)

问题描述 投票:0回答:1

我是 python 新手,我正在浏览 OpenAI 上提供的这段代码。它正在尝试读取 CSV 并创建数据框。我检查了数据框中已经有一个名为

"babbage_search"
的列,其中包含向量。我不明白的是为什么我们需要在这行代码中传递
eval
作为参数:

df["babbage_search"] = df.babbage_search.apply(eval).apply(np.array)

如果删除

.apply(eval)
,我会收到错误:

ufunc 'multiply' did not contain a loop with signature matching types (dtype('<U45750'), dtype('<U23')) -> None

这是代码片段:

import pandas as pd
import numpy as np
from openai.embeddings_utils import get_embedding, cosine_similarity

datafile_path = "../ReviewsWithEmbeddings.csv"  
df = pd.read_csv(datafile_path)
df["babbage_search"] = df.babbage_search.apply(eval).apply(np.array)

# search through the reviews for a specific product
def search_reviews(df, product_description, n=3, pprint=True):
    embedding = get_embedding(
        product_description,
        engine="text-search-babbage-query-001"
    )
    df["similarities"] = df.babbage_search.apply(lambda x: cosine_similarity(x, embedding))
    print('SIMILARITIES:', df.similarities)
    res = (
        df.sort_values("similarities", ascending=False)
        .head(n)
        .combined.str.replace("Title: ", "")
        .str.replace("; Content:", ": ")
    )
    if pprint:
        for r in res:
            print(r[:200])
    return res


res = search_reviews(df, "Christmas gift", n=3)
python-3.x pandas dataframe
1个回答
0
投票

此模式用于将字符串值转换为 python 结构,然后转换为 numpy 数组。

该模式在 openai 的多个教程中使用。 在阅读他们的 web-qa-embeddings 教程时,我对此感到困惑。

使用 eval() 而不是解析器会存在一些黑客攻击和安全风险。

  • .apply(eval)
    eval()
    函数应用于嵌入列中的每个元素。
    eval()
    将字符串计算为 Python 表达式。 (如果数据不受信任,这将是一个巨大的安全风险)。 当列包含表示 python 数据的字符串时使用。 例如包含数组 repr 的字符串:
    "[1, 2, 3]"
  • .apply(np.array)
    eval()
    的结果(可能是列表或其他 Python 对象)转换为 numpy 数组。

包含嵌入的字段将是高维向量

"[-0.0010764977196231484, 0.01885923556983471, 0.029220420867204666, ... ]"
的字符串表示形式。 应用 Eval 将其转换为 python 数组,然后第二个应用将其转换为 numpy 数组。

eval
更安全的选择包括
ast.literal_eval
json.loads

© www.soinside.com 2019 - 2024. All rights reserved.