【问题标题】:Better use a tuple or numpy array for storing coordinates更好地使用元组或 numpy 数组来存储坐标
【发布时间】:2011-02-03 13:27:30
【问题描述】:

我正在将一个 C++ 科学应用程序移植到 python,由于我是 python 新手,我想到了一些问题:

1) 我正在定义一个包含坐标 (x,y) 的类。这些值将被访问多次,但它们只会在类实例化之后被读取。在内存和访问时间方面,使用元组还是 numpy 数组更好?

2) 在某些情况下,这些坐标将用于构建复数,在复数函数上求值,并且将使用该函数的实部。假设没有办法将这个函数的实部和复数分开,并且最后必须使用实部,也许直接使用复数来存储(x,y)更好?在 python 中从复杂到真实的转换的开销有多严重? c++ 中的代码做了很多这样的转换,这在代码中是一个很大的减速。

3) 还必须执行一些坐标变换,对于坐标,x 和 y 值将分别访问,完成变换并返回结果。坐标变换是在复平面上定义的,所以直接使用 x 和 y 分量还是比依赖复变量更快?

谢谢

【问题讨论】:

  • 为什么不直接使用 numpy 复数数组?
  • 这是算法意义上的最佳方法,但据我的测试显示,这是可能的最慢组合。

标签: python arrays numpy tuples complex-numbers


【解决方案1】:

在内存消耗方面,numpy 数组比 Python 元组更紧凑。 numpy 数组使用单个连续的内存块。 numpy 数组的所有元素都必须是声明的类型(例如 32 位或 64 位浮点数)。Python 元组不一定使用连续的内存块,元组的元素可以是任意 Python 对象,这通常比 numpy 数值类型消耗更多的内存。

所以这个问题对于 numpy 来说是一个不折不扣的胜利,(假设数组的元素可以存储为 numpy 数值类型)。

关于速度的问题,我认为选择归结为一个问题,“你能矢量化你的代码吗?”

也就是说,您能否将您的计算表达为对整个数组元素进行的操作。

如果代码可以向量化,那么 numpy 很可能会比 Python 元组更快。 (我能想象到的唯一情况是,如果你有很多非常小的元组。在这种情况下,形成 numpy 数组的开销和导入 numpy 的一次性成本可能会淹没矢量化的好处。)

无法向量化的代码示例是,如果您的计算涉及查看数组z 中的第一个复数,执行生成整数索引idx 的计算,然后检索@987654323 @,对该数字进行计算,生成下一个索引idx2,然后检索z[idx2],等等。这种类型的计算可能无法矢量化。在这种情况下,您不妨使用 Python 元组,因为您将无法利用 numpy 的优势。

我不会担心访问复数的实部/虚部的速度。我的猜测是矢量化问题很可能决定哪种方法更快。 (不过,顺便说一下,numpy 可以将复数数组转换为实数部分,只需跨过复数数组,跳过每隔一个浮点数,并将结果视为浮点数。此外,语法非常简单:如果@987654326 @ 是一个复杂的 numpy 数组,然后 z.real 是浮点 numpy 数组的实部。这应该比使用属性查找的列表理解的纯 Python 方法快得多:[z.real for z in zlist]。)

出于好奇,您将 C++ 代码移植到 Python 的原因是什么?

【讨论】:

  • 只是为了测试 Python 对象结构是否更适合我的应用程序,并尝试使用 scipy 例程。到目前为止,我坚持使用 C++ - 在我的测试中,速度至少快了 2 个数量级!
  • 此外,在 C++ 代码中访问数字的实部和虚部会大大减慢速度。
  • 是的,使用 Python 有充分的理由,例如可读性和快速的代码开发,但我还没有遇到任何将代码从 C/C++ 移植到 Python 并享受加速的示例。通常当 Python 代码出现瓶颈时,人们建议用 C/C++ 重写该函数并从 Python 中调用它。
【解决方案2】:

具有额外维度的numpy 数组在内存使用方面更紧凑,并且至少和numpy 元组数组一样快!复数至少一样好甚至更好,包括你的第三个问题。顺便说一句,您可能已经注意到 - 虽然比您晚提出的问题得到了很多答案 - 您正在闲置:部分原因无疑是在一个问题中提出 三个 问题会使响应者关闭.为什么不每个问题只问一个问题?好像你不会因为问题或任何事情而被收费,你知道...!-)

【讨论】:

    猜你喜欢
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多