【问题标题】:python numpy optimization n-dimensional projectionpython numpy优化n维投影
【发布时间】:2012-11-25 04:21:06
【问题描述】:

我对 python 比较陌生,对优化和加速这个功能的任何想法都很感兴趣。对于我正在做的数值计算,我必须调用它数万次,它占用了代码总计算时间的主要部分。 我已经用 c 编写了这个,但我很想看看有什么技巧可以让它在 python 中运行得更快。

此代码根据http://en.wikipedia.org/wiki/Stereographic_projection 计算 bigD 长度向量到 littleD 长度向量的立体投影。变量 a 是一个长度为 96 的 numpy 数组。

import numpy as np 
def nsphere(a):
    bigD = len(a)
    littleD = 3
    temp = a
# normalize before calculating projection
    temp = temp/np.sqrt(np.dot(temp,temp))
# calculate projection
    for i in xrange(bigD-littleD + 2,2,-1 ):
        temp = temp[0:-1]/(1.0 - temp[-1])
    return temp
#USAGE:
q = np.random.rand(96)
b = nsphere(q)
print b

【问题讨论】:

  • 我很困惑——在你的 for 循环中,你没有在任何地方使用索引 i。所以你只是多次将temp除以1.0-temp[-1]
  • @tpg2114 - 在循环的每次迭代中,temp 会缩小一个,因为[0:-1] 不包括最后一项。所以操作并不像你建议的那么简单。但我同意在从未被引用时显式控制 i 的开始和停止值是很奇怪的。
  • 嗨 - 是的,我没有被使用,这是一种重复这个过程 96-3 次的愚蠢方式,但实际上就是这样。我想知道是否每次将 temp[] 重新分配给 1 元素较短的向量很慢,将长度为 96、95、94 的向量的 96-3 长度列表预分配给 3 会更快吗?我不知道这在 python 中是如何工作的。

标签: python optimization numpy projection


【解决方案1】:

这应该更快:

def nsphere(a, littleD=3):
    a = a / np.sqrt(np.dot(a, a))
    z = a[littleD:].sum()
    return a[:littleD] / (1. - z)

请进行数学运算以确认这实际上与您的迭代算法相同。

显然,这里的主要加速将来自这样一个事实,即这是一个 O(n) 算法,它取代了用于计算投影的 O(n**2) 算法。但特别是为了在 python 中加快速度,你想要“矢量化你的内部循环”。意思是尽量避免循环和其他任何会在代码的最关键性能部分产生高 python 开销的东西,而是尝试使用高度优化的 python 和 numpy 内置函数。希望对您有所帮助。

【讨论】:

  • @Bi Rico - 谢谢,这确实运行得更快,但它计算的东西不一样,结果也不同。这必然是一个 N^2 问题。我应该提供有关其工作原理的更多详细信息吗?
  • @user1850461 如果您仔细计算数学,我相信您会发现这与您在问题中提供的功能相同。我还针对您问题中的函数测试了这个函数,它给出了相同的结果。当然,如果您提供了您正在尝试优化的真实功能的简化版本,这可能没有那么有用。
  • 好的,问题解决了。我的函数(此处未显示,在我使用的实际代码中-我的混淆错误)在返回之前对结果进行了规范化,而你的函数没有,我添加了一行来返回规范化的结果,它们现在与真实数据完全一致。非常感谢这个解决方案,根据输入数据的维度,它的运行速度提高了 40~100 倍,非常有帮助!
猜你喜欢
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2022-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 2014-05-04
相关资源
最近更新 更多