最好使用元组或numpy数组来存储坐标 我将一个C++科学应用移植到Python上,因为我对Python是新手,我想到了一些问题:

最好使用元组或numpy数组来存储坐标 我将一个C++科学应用移植到Python上,因为我对Python是新手,我想到了一些问题:,python,arrays,numpy,tuples,complex-numbers,Python,Arrays,Numpy,Tuples,Complex Numbers,1) 我正在定义一个包含坐标(x,y)的类。这些值将被访问几次,但它们仅在类实例化后读取。在内存和访问时间方面,使用元组或numpy数组更好吗 2) 在某些情况下,这些坐标将用于构建一个复数,在一个复数函数上进行计算,并使用该函数的实部。假设没有办法将这个函数的实部和复部分开,并且最终必须使用实部,那么最好直接使用复数来存储(x,y)?python中从复杂到真实的转换开销有多大?C++中的代码做了很多这些转换,这是代码中的一个很大的减速。 3) 此外,还必须执行一些坐标转换,对于坐标,将分别访问

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

2) 在某些情况下,这些坐标将用于构建一个复数,在一个复数函数上进行计算,并使用该函数的实部。假设没有办法将这个函数的实部和复部分开,并且最终必须使用实部,那么最好直接使用复数来存储(x,y)?python中从复杂到真实的转换开销有多大?C++中的代码做了很多这些转换,这是代码中的一个很大的减速。 3) 此外,还必须执行一些坐标转换,对于坐标,将分别访问x和y值,完成转换并返回结果。坐标变换是在复杂平面中定义的,因此直接使用组件x和y比依赖复杂变量更快吗


谢谢

A
numpy
具有额外维度的数组在内存使用方面更加紧凑,而且至少同样快!,作为元组的
numpy
数组;复数至少和你的第三个问题一样好,甚至更好。顺便说一句,你可能已经注意到,虽然比你晚问的问题得到了大量的答案,但你却没有回答:部分原因无疑是在一个问题中问三个问题会让回答者感到厌烦。为什么不每个问题问一个问题呢?这并不是说你会因为问题或任何事情而被收费,你知道…!-)

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

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

在速度问题上,我认为选择可以归结为一个问题,“你能把你的代码矢量化吗?”

也就是说,您可以将计算表示为对整个数组按元素进行的操作

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

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

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


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

为什么不使用一个复杂的数字数组?这是算法意义上的最佳方法,但就我的测试来看,这是最慢的组合。试着做些简单的动作。到目前为止,我在测试中坚持C++,至少快了2个数量级!此外,访问数字的实部和虚部是C++代码中的一大减速。是的,使用Python有很好的理由,比如可读性和快速代码开发,但是我没有遇到代码从C/C++移植到Python并享受加速的任何例子。通常,当Python代码出现瓶颈时,人们建议用C/C++重写该函数并从Python调用它。