【发布时间】:2021-07-20 07:56:51
【问题描述】:
我有数以万计的元组列表,其中列表中的每个元组都由一个 (int, float) 对组成。我希望能够循环遍历所有元组列表以找到 (int, float) 对,其中 float 是元组列表中浮点数的最大值。考虑几个元组列表:
[
[(0, 0.3792), (3, 0.5796)],
[0, 0.9365), (1, 0.0512), (18, 0.0123),
[(13, 0.8642)],
[(0, 0.6249), (1, 0.01), (2, 0.01), (3, 0.01), (4, 0.01), (5, 0.01)]
]
对于每个元组列表,我想找到第二个数字最大化的对(例如,对于第一个列表,我想要 (3, 0.5796);对于第四个项目,应该返回 (0, 0.6249))。我目前的做法是将元组变成numpy数组,然后找到argmax和max:
def get_max(doc: List[Tuple[int, float]]) -> Tuple[int, float]:
topic_prob_array = np.array(doc, dtype=np.dtype('int,float'))
return topic_prob_array['f0'][np.argmax(topic_prob_array['f1'])], np.max(topic_prob_array['f1'])
我希望把它变成一个 numpy 矢量化函数(通过vec_func = np.vectorized(get_max, otypes=[int,float]) 或 numpy ufunc(通过vec_func = np.fromfunc(get_max, nin=1, nout=1)。我不确定我是否正确格式化了输入和输出。我的理由是我正在发送一个单个元组列表并返回单个元组,因此 nin=1, nout=1。但是,我无法成功地运行它的矢量化版本。
我也尝试了一个不依赖numpy的解决方案:
def get_max(doc: List[Tuple[int, float]]) -> Tuple[int, float]:
ids, probabilities = zip(*doc)
return ids[np.argmax(probabilities)], np.max(probabilities)
两者的运行时间大致相同。对于我大约 80k 的列表,这两种实现都需要大约 1 分 10 秒。如果可能的话,我真的很想把它写下来。
【问题讨论】:
-
你在寻找一个 numpy 的答案吗?
-
np.vectorize尽管有这个名字,但在快速编译函数的意义上,它并没有“向量化”。np.frompyfunc比np.vectorize快,但仍然不比简单的列表理解快。此外,它们将“标量”值传递给函数。你想传递一个子列表。
标签: python arrays numpy tuples vectorization