Python 在字典与numpy数组中查找最大值的性能

Python 在字典与numpy数组中查找最大值的性能,python,performance,dictionary,numpy,max,Python,Performance,Dictionary,Numpy,Max,我收集了大量的(以千计)单词:value(float)对。我需要找到最佳值并提取相应的关联词。例如,我有(a,2.4),(b,5.2),(c,1.2),(d,9.2),(e,6.3),(f,0.4)。我想要(d,9.2)作为输出 目前,我正在使用字典来存储这些元组,并使用max操作符来检索字典中的最大键值。我想知道numpy阵列是否更有效。在这里征求专家意见。我看不出numpy阵列在这种情况下对您有什么帮助 特别是,将一个数据结构转换为另一个数据结构(在您的例子中是numpy数组或heapq中的

我收集了大量的(以千计)单词:value(float)对。我需要找到最佳值并提取相应的关联词。例如,我有(a,2.4),(b,5.2),(c,1.2),(d,9.2),(e,6.3),(f,0.4)。我想要(d,9.2)作为输出


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

我看不出numpy阵列在这种情况下对您有什么帮助

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

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

>>> li = [('a',  10), ('b', 30), ('c', 20)]
>>> max(li, key=lambda e : e[1])[0]
'b'
如果您也对最低值或弹出列表之类的内容感兴趣,那么您找到的值可以通过排序传递(因此您只需检查原始列表一次!):

或:


在这里使用Numpy需要将浮点值保存在单独的
ndarray
中。使用
argmax
查找max value的索引,并从单独的列表中获取单词。这是非常快的,但是构造ndarray只找到max是不可能的。例如:

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将其考虑在内)

您需要在一个结构中存储元组,还是可以动态生成元组?如果您需要多个最大项目,可以使用“heapq”。你正在解决什么样的问题?你确定这部分是问题的根源吗?我需要将元组存储在一个结构中。我只想找到最大数值和对应的‘键’。“我想知道numpy数组是否更有效”。。。“答案是…?”麦克在答案中添加了结论。我们真的需要OP提供更多信息来回答这个问题。他说他目前正在使用dict存储这个单词-值对,他愿意将它们存储在一个ndarray中吗?Bago,是的,我愿意将它存储在一个ndarray中。我要问Janne的问题是,如果考虑到Numpy数组的构造,Numpy>List/Dict是否仍然有效?@Denzil否,如果只使用max,请不要使用Numpy数组。在我的示例中,fd函数就是这么做的,它是最慢的.Mac,感谢您的详细回复。请注意,元组可以直接构造为ndarray,而不是先将其放入字典,然后再转换为ndarray。原始帖子中的示例仅用于演示。
>>> sorted(li, key=lambda e: e[1])[-1][0]
'b'
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]