【问题标题】:Performance for finding the maximum value in a dictionary versus numpy array在字典中查找最大值与 numpy 数组的性能
【发布时间】:2012-01-01 12:36:22
【问题描述】:

我有大量(数千)字:值(浮点)对。我需要找到最好的值并提取相应的关联词。例如,我有 (a,2.4),(b,5.2),(c,1.2),(d,9.2),(e,6.3),(f,0.4)。我想要 (d,9.2) 作为输出。

目前,我正在使用字典来存储这些元组,并使用 max 运算符来检索字典中的最大键值。我想知道一个 numpy 数组是否会更有效。在这里征求专家意见。

【问题讨论】:

  • 您需要将元组存储在一个结构中还是可以即时生成它们?如果需要多个最大项,可以使用 'heapq' docs.python.org/library/heapq.html。您正在解决什么样的问题,您确定这部分是麻烦的根源吗?
  • 我需要将元组存储在一个结构中。我只想找到最大的数值和对应的'key'。

标签: python performance dictionary numpy max


【解决方案1】:

在这种情况下,我看不出 numpy 数组对您有何帮助。

特别是,将数据结构转换为另一个数据结构(在您的情况下是 numpy 数组或 heapq 中的元组列表)将比找到迭代每个元组的最大值慢得多)。这是因为转换数据结构还需要迭代原始结构,加上为新结构实例化一个对象,加上将值存储到新结构中,再加上使用新结构来获取请求的值。

使用列表的内置函数或方法很可能会加快计算速度。我能想到的最简单的实现:

>>> li = [('a',  10), ('b', 30), ('c', 20)]
>>> max(li, key=lambda e : e[1])[0]
'b'

如果您也对诸如最低值或从列表中弹出您找到的值可以通过排序(因此您只检查一次原始列表!)等内容感兴趣,其他可能的方法:

>>> li = [('a',  10), ('b', 30), ('c', 20)]
>>> li.sort(key=lambda e : e[1])
>>> li
[('a', 10), ('c', 20), ('b', 30)]
>>> li[-1][0]
'b'

或者:

>>> sorted(li, key=lambda e: e[1])[-1][0]
'b'

HTH!

【讨论】:

  • Mac,感谢您的详细回复。请注意,元组可以直接构造为 ndarray,而不是先将其放入字典然后再转换为 ndarray。原帖中的示例仅用于演示。
【解决方案2】:

在这里使用 Numpy 将涉及将浮点值保存在单独的 ndarray 中。使用argmax 查找最大值索引并从单独的列表中获取单词。这是非常快的,但构造 ndarray 只是为了找到最大值不是。示例:

import numpy as np
import operator

names = [str(x) for x in xrange(10000)]
values = [float(x) for x in xrange(10000)]
tuples = zip(names, values)
dic = dict(tuples)
npvalues = np.fromiter(values, np.float)

def fa():
    return names[npvalues.argmax()]

def fb():
    return max(tuples, key=operator.itemgetter(1))[0]

def fc():
    return max(dic, key=dic.get)

def fd():
    v = np.fromiter((x[1] for x in tuples), np.float)
    return tuples[v.argmax()][0]

时序:fa 67 µs,fb 2300 µs,fc 2580 µs,fd 3780 µs。

因此,当不考虑构建 Numpy 数组的时间时,使用 Numpy (fa) 比使用普通列表 (fb) 或字典 (fc) 快 30 倍以上。 (fd 考虑在内)

【讨论】:

  • “我想知道一个 numpy 数组是否会更高效”...答案是...?
  • @mac 为答案添加了结论。
  • 我们确实需要来自 OP 的更多信息来回答这个问题。他说他目前正在使用 dict 存储这个单词值对,他愿意将它们存储在 ndarray 中吗?
  • Bago,是的,我愿意将其存储在 ndarray 中。我对 Janne 的问题是,如果考虑到 Numpy 数组构造,Numpy > List/Dict 是否仍然有效?
  • @Denzil 不,如果取最大值是唯一的用途,请不要使用 Numpy 数组。在我的示例中,fd 函数就是这样做的,而且它是最慢的。
猜你喜欢
  • 2016-08-07
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
相关资源
最近更新 更多