Numpy:2d list min max很慢

时间:2015-02-05 09:31:05

标签: python numpy

我对numpy全新,无法找到解决方案。 我在python中有一个2d的浮点数列表,如:

list1[0..8][0..2] 

例如:

print(list1[0][0])
> 0.1122233784

现在我想找到最小值和最大值:

b1 = numpy.array(list1)
list1MinX, list1MinY, list1MinZ = b1.min(axis=0)
list1MaxX, list1MaxY, list1MaxZ = b1.max(axis=0)

我需要在循环中执行大约一百万次。

它工作正常,但它比我以前的原生python方法慢了3倍。

(1:15分[numpy] vs 0:25分[原生])

我做错了什么? 我已经读过列表转换可能是问题,但我不知道如何做得更好。

修改

请求一些非伪代码,尽管在我的脚本中,列表是以另一种方式创建的。

import numpy
import random

def moonPositionNow():
   #assume we read like from a file, line by line
   #nextChunk = readNextLine()
   #the file is build like this
   #x-coord
   #y-coord
   #z-coord
   #x-coord
   #...
   #but we don't have that data here, so as a **placeholder** we return a random number
   nextChunk = random.random()
   return nextChunk  

for w in range(1000000):        
    list1 = [[moonPositionNow() for i in range(3)] for j in range(9)]
    b1 = numpy.array(list1)
    list1MinX, list1MinY, list1MinZ = b1.min(axis=0)
    list1MaxX, list1MaxY, list1MaxZ = b1.max(axis=0)        

#Print out results   

虽然列表创建可能是瓶颈但我保证在原始代码中它不是问题。

EDIT2:

更新了示例代码以澄清,我不需要一个随机数字的numpy数组。

2 个答案:

答案 0 :(得分:1)

问题出现是因为您将python列表传递给numpy函数。如果将numpy数组作为参数传递,numpy函数会明显加快。

#Create numpy numbers
nptest = np.random.uniform(size=(10000, 10))
#Create a native python list
listtest = list(nptest)
#Compare performance
%timeit np.min(nptest, axis=0)
%timeit np.min(listtest, axis=0)

输出

1000 loops, best of 3: 394 µs per loop
100 loops, best of 3: 20 ms per loop

编辑:添加了有关如何评估网格上的成本函数的示例。

以下评估网格上的二次成本函数,然后沿第一个轴取最小值。特别是,np.meshgrid是您的朋友。

def cost_function(x, y):
    return x ** 2 + y ** 2

x = linspace(-1, 1)
y = linspace(-1, 1)

def eval_python(x, y):
    matrix = [cost_function(_x, _y) for _x in x for _y in y]
    return np.min(matrix, axis=0)

def eval_numpy(x, y):
    xx, yy = np.meshgrid(x, y)
    matrix = cost_function(xx, yy)
    return np.min(matrix, axis=0)

%timeit eval_python(x, y)
%timeit eval_numpy(x, y)

输出     100个循环,最佳3:每循环13.9 ms     10000个循环,最佳3:每循环136μs

最后,如果您无法在此表单中转换问题,则可以预先分配内存,然后填写每个元素。

matrix = np.empty((num_x, num_y))
for i in range(num_x):
    for j in range(num_y):
        matrix[i, j] = cost_function(i, j)

答案 1 :(得分:1)

由于您的数据可以作为Python列表使用,因此本机实现(可能调用某些优化的C代码)可能比首先转换为numpy然后调用优化的C代码更快。

你基本上将数据循环两次:一次用于将python对象转换为numpy数组,一次用于计算最大值或最小值。 本机实现(我假设它类似于在Python列表上调用min / max)只需要循环数据一次。

此外,似乎numpy的min / max函数出乎意料地慢:https://stackoverflow.com/a/12200671/3005167