我对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数组。
答案 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