【问题标题】:Where can I find the efficiency O(n) of some Numpy methods?我在哪里可以找到一些 Numpy 方法的效率 O(n)?
【发布时间】:2015-08-06 07:22:39
【问题描述】:

我正在做一个学校项目,他们询问了一些 Numpy 方法的效率 O(n),我找不到它们。谁能告诉我在哪里可以找到这些?

示例方法如:

numpy.linspace(x,y,z) numpy.meshgrid(x,y) numpy.zeroes(x,y)

【问题讨论】:

  • 我认为没有地方可以查找它们。您将不得不考虑算法实际上做了什么来推断其复杂性。例如np.ones(n) 必须为 n 个浮点数分配内存,然后在每个内存单元中写入 1。总共它必须写 n 个,所以你在O(n)
  • 哦,我明白了..但这不适用于 meshgrid 和 linspace...

标签: performance numpy processing-efficiency


【解决方案1】:

您可以简单地测量不同问题规模的执行时间,以估算时间复杂度,

  • numpy.zeros(n)non-deterministic
  • numpy.meshgrid(x,y) : O(n**2)
  • numpy.linspace(0, 1, n) : O(n**1.6)

例如,下面是测量numpy.meshgrid(x,y) 时间复杂度的代码,它也可以用于其他 numpy 函数,

In [1]: import numpy as np
   ...: from time import time
   ...: import matplotlib.pyplot as plt
   ...: from scipy.optimize import curve_fit
   ...: %matplotlib inline
   ...: 
   ...: def complexity_model(x, n, A, C):
   ...:     return A*x**n + C
   ...: 
   ...: problem_size = np.logspace(2, 4, 10)
   ...: 
   ...: res = []
   ...: for N in problem_size:
   ...:     x = np.linspace(0, 1, N)
   ...:     y = x.copy()
   ...:     
   ...:     t0 = time()
   ...:     np.meshgrid(x,y)
   ...:     dt = time() - t0
   ...:     res.append(dt)
   ...: 
   ...: nn = np.logspace(np.log10(problem_size.min()), np.log10(problem_size.max()), 100)  
   ...: 
   ...: time_to_solution = np.asarray(res)
   ...: fig, ax = plt.subplots(1,1)
   ...: ax.loglog(problem_size, time_to_solution, 'o-b')
   ...: 
   ...: mask = problem_size > 100 # ignore initial points
   ...: 
   ...: popt, _ = curve_fit(complexity_model, problem_size[mask],
   ...:                               time_to_solution[mask],
   ...:                               p0=(1.0, 1.0,  0.0) )
   ...: print(popt)
   ...: ax.loglog(nn, complexity_model(nn, *popt), '--k')
   ...: 
   ...: 
   ...: ax.set_xlabel('Problem size: N')
   ...: ax.set_ylabel('Time to solution 
  [  1.94816942e+00   1.40955397e-08  -7.33862899e-04]

给出以下曲线,

对于足够大的数组大小,numpy.meshgrid(x,y) 的时间复杂度为O(n**α)α = 1.95 ≈ 2

【讨论】:

  • 非常感谢您提供这个深入的解决方案。选择它作为正确答案:)
  • numpy.zeros(n): O(1) 似乎很可疑。这意味着您可以比用0 填充每个内存单元做得更好。你确定这是可能的吗?
  • @cel 是的,我也这么认为。粗略地说,应该是相应内存分配的时间复杂度。然而,执行一个maloc 的时间似乎并不确定(参见answer)。例如,%timeit -n 1 np.zeros(100000) 在我的笔记本电脑上提供介于 30160 µs 之间的任何内容。我更新了答案以反映这一点。
  • @rth,是的,我认为这是计时方法的限制。在这种情况下,可能发生了与算法本身的时间复杂度无关的奇怪资源优化。
猜你喜欢
  • 2011-06-16
  • 1970-01-01
  • 2017-05-13
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多