有没有一种方法,使numpy.argmin()一样快,MIN()? [英] Is there a way to make numpy.argmin() as fast as min()?

查看:480
本文介绍了有没有一种方法,使numpy.argmin()一样快,MIN()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到沿着一个非常大的2D numpy的数组中的一维的最低数组索引。我发现,这是很慢的(已经尝试了瓶颈,这只是一个很小的改进加速它)。但是,考虑直最小似乎更快一个数量级:

 导入numpy的是NP
进口时间randvals = np.random.rand(3000,160000)
开始=选定了time.time()
MINVAL = randvals.min(轴= 0)
打印拿着{0:.2f}秒来计算分.format(选定了time.time() - 启动)
开始=选定了time.time()
minindex = np.argmin(randvals,轴= 0)
打印拿着{0:.2f}秒来计算argmin.format(选定了time.time() - 启动)

在我的机器上这个输出:

 接过0.83秒来计算分
花9.58秒计算argmin

是否有任何理由argmin这么多慢?有什么办法加快它可比到最小?


解决方案

 在[1]:进口numpy的为NP在[2]为:a = np.random.rand(3000,16000)在[3]:%timeit a.min(轴= 0)
1循环,最好的3:每循环421毫秒在[4]:%timeit a.argmin(轴= 0)
1循环,最好的3:每循环1.95小号在[5]:%timeit a.min(轴= 1)
1循环,最好的3:每循环302毫秒在[6]:%timeit a.argmin(轴= 1)
1循环,最好的3:每循环303毫秒在[7]:%timeit a.T.argmin(轴= 1)
1循环,最好的3:每循环1.78小号在[8]:%​​timeit np.asfortranarray(一).argmin(轴= 0)
1循环,最好的3:每循环1.97小号在[9]:B = np.asfortranarray(一)在[10]:%timeit b.argmin(轴= 0)
1循环,最好的3:每循环329毫秒

也许是足够聪明的数组(因此具有缓存局部性)在完成其工作顺序和 argmin 在数组跳来跳去(造成大量高速缓存未命中)?

无论如何,如果你愿意坚持 randvals 从一开始就用Fortran有序阵列,它会更快,虽然复制到Fortran的排序没有按' ŧ帮助。

I'm trying to find the minimum array indices along one dimension of a very large 2D numpy array. I'm finding that this is very slow (already tried speeding it up with bottleneck, which was only a minimal improvement). However, taking the straight minimum appears to be an order of magnitude faster:

import numpy as np
import time

randvals = np.random.rand(3000,160000)
start = time.time()
minval = randvals.min(axis=0)
print "Took {0:.2f} seconds to compute min".format(time.time()-start)
start = time.time()
minindex = np.argmin(randvals,axis=0)
print "Took {0:.2f} seconds to compute argmin".format(time.time()-start)

On my machine this outputs:

Took 0.83 seconds to compute min
Took 9.58 seconds to compute argmin

Is there any reason why argmin is so much slower? Is there any way to speed it up to comparable to min?

解决方案

In [1]: import numpy as np

In [2]: a = np.random.rand(3000, 16000)

In [3]: %timeit a.min(axis=0)
1 loops, best of 3: 421 ms per loop

In [4]: %timeit a.argmin(axis=0)
1 loops, best of 3: 1.95 s per loop

In [5]: %timeit a.min(axis=1)
1 loops, best of 3: 302 ms per loop

In [6]: %timeit a.argmin(axis=1)
1 loops, best of 3: 303 ms per loop

In [7]: %timeit a.T.argmin(axis=1)
1 loops, best of 3: 1.78 s per loop

In [8]: %timeit np.asfortranarray(a).argmin(axis=0)
1 loops, best of 3: 1.97 s per loop

In [9]: b = np.asfortranarray(a)

In [10]: %timeit b.argmin(axis=0)
1 loops, best of 3: 329 ms per loop

Maybe min is smart enough to do its job sequentially over the array (hence with cache locality), and argmin is jumping around the array (causing a lot of cache misses)?

Anyway, if you're willing to keep randvals as a Fortran-ordered array from the start, it'll be faster, though copying into Fortran-ordered doesn't help.

这篇关于有没有一种方法,使numpy.argmin()一样快,MIN()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆