缩放浮动列表的最快方法

时间:2015-07-19 10:58:28

标签: python performance numpy

我有一个从机器学习算法得到的浮点数列表。所有这些浮点数介于0和1之间:

probs = [proba[0] for proba in self.classifier.predict_proba(x_test)]

probs是我的浮动列表。 predict_proba()函数通常返回一个numpy数组。获取列表大约需要9秒钟,列表最终包含大约60k的值。

我想将列表中的所有值与列表中的最高值进行缩放或标准化。

通常,我会这样做:

maximum = max(probs)
list_values = [proba / maximum for proba in probs]

但是对于60k的值,大约需要2分钟。我想缩短它。

你对我如何参加更好的演出有什么想法吗?

4 个答案:

答案 0 :(得分:2)

如果您不介意使用外部库,numpy可能值得研究:

import numpy
probs = numpy.array([proba[0] for proba in self.classifier.predict_proba(x_test)])
list_values = probs/maximum

答案 1 :(得分:0)

使用numpy的另一种方法,如果你的概率列表很大,可能会更快,就是将整个概率转换为numpy数组,然后对它进行操作:

import numpy as np

probs = np.asarray(self.classifier.predict_proba(x_test))

list_values = probs[:, 0] / probs.max()

第一行会将您的所有概率转换为N x M数组(其中N是您的样本,M是您的班级数。)

第二行将选择第一个类的所有概率([:, 0]表示第0列的所有行,这将产生大小为N的向量)并将其除以最大值。

您可以将此扩展到所有概率:

all_probs = probs / probs.max()

以上将对所有类的所有概率进行标准化。之后您可以像all_probs[:, i]那样访问它们,其中i是感兴趣的类。

答案 2 :(得分:0)

你应该使用Scikit learn's normalize。

from sklearn.preprocessing import normalize

答案 3 :(得分:0)

如果您希望最终结果为numpy.array,那么将列表转换为numpy数组并直接使用数组除法将比列表理解更快。示例 -

import numpy as np
probsnp = np.array([proba[0] for proba in self.classifier.predict_proba(x_test)])
maximum = probs.max()
list_values = probs/maximum

时间测试的例子 -

In [46]: import numpy.random as ndr

In [47]: probs = ndr.random_sample(1000)

In [48]: probs.shape
Out[48]: (1000,)

In [49]: def func1(probs):
   ....:     maximum = max(probs)
   ....:     probsnew = [i/maximum for i in probs]
   ....:     return probsnew
   ....:

In [50]: def func2(probs):
   ....:     maximum = probs.max()
   ....:     probsnew = probs/maximum
   ....:     return probsnew
   ....:

In [51]: %timeit func1(probs)
The slowest run took 229.79 times longer than the fastest. This could mean that an intermediate result is being cached
1000 loops, best of 3: 279 µs per loop

In [52]: %timeit func1(probs)
1000 loops, best of 3: 278 µs per loop

In [53]: %timeit func2(probs)
The slowest run took 356.45 times longer than the fastest. This could mean that an intermediate result is being cached
10000 loops, best of 3: 81 µs per loop

In [54]: %timeit func1(probs)
1000 loops, best of 3: 278 µs per loop

In [55]: %timeit func2(probs)
10000 loops, best of 3: 81.5 µs per loop

numpy方法只需要列表理解的1/3。

使用numpy.array()转换作为func2的一部分的定时测试(在上面的示例中) -

In [60]: probslist = [p for p in probs]

In [61]: def func2(probs):
   ....:     probsnp = np,array(probs)
   ....:     maxprobs = probsnp.max()
   ....:     probsnew = probsnp/maxprobs
   ....:     return probsnew
   ....:

In [65]: %timeit func1(probslist)
1000 loops, best of 3: 212 µs per loop

In [66]: %timeit func2(probslist)
10000 loops, best of 3: 198 µs per loop

In [67]: probs = ndr.random_sample(60000)

In [68]: probslist = [p for p in probs]

In [74]: %timeit func1(probslist)
100 loops, best of 3: 11.5 ms per loop

In [75]: %timeit func2(probslist)
100 loops, best of 3: 5.79 ms per loop

In [76]: %timeit func1(probslist)
100 loops, best of 3: 11.4 ms per loop

In [77]: %timeit func2(probslist)
100 loops, best of 3: 5.81 ms per loop

似乎使用numpy数组仍然要快一点。