我正在使用一个python程序,它使用numpy数组作为数组的标准数据类型。对于繁重的计算,我将数组传递给C ++库。为此,我使用pybind。但是,我需要使用python 2016-09-10
。我通过以下方式从list
数组和numpy
进行转换:
list
此转换产生多少开销?我希望它不会创建一个全新的副本。 Numpy参考说:
ndarray.tolist()
将数组数据的副本作为(嵌套)Python列表返回。数据项 被转换为最接近的兼容Python类型。
答案 0 :(得分:3)
很多。对于简单的内置类型,您可以在对象上使用sys.getsizeof
来确定与该对象关联的内存开销(对于容器,这不包括存储在其中的值,只包括用于存储它们的指针)。
因此,例如,list
100个小int
s(但大于256以避免小int
缓存)(在我的3.5.1 Windows x64安装上):< / p>
>>> sys.getsizeof([0] * 100) + sys.getsizeof(0) * 100
3264
或大约需要3 KB的内存。如果这些相同的值存储在numpy
array
int32
中,每个数字没有Python对象,并且没有每个对象指针,则大小将降至大约100 * 4(加上另外几十个字节,对于array
对象开销本身而言,在500字节以下。对于每个额外的小int
,增量成本为24字节(尽管如果它在小型int缓存中为-5到256 IIRC的值,它是免费的),以及8字节对于list
中的存储,总共32个字节,而C级类型为4,大约是存储要求的8倍(并且您仍然存储原始对象)。
如果你有足够的内存来处理它,那就这样吧。但除此之外,您可能会尝试查看一个包装,它允许您传递缓冲区协议支持对象(Py3上的numpy.array
,array.array
,通过内存视图切片分配填充的ctypes
数组等。)所以不需要转换为Python级别类型。
答案 1 :(得分:3)
是的,它将是新副本。数组的数据布局与列表的数据布局非常不同。
数组具有形状和步幅等属性,以及包含元素的1d数据缓冲区 - 只是一组连续的字节。它是将其视为浮点数,整数,字符串,1d,2d等的其他属性和代码。
列表是指针的缓冲区,每个指针指向内存中的对象。它可能指向数字,字符串或其他列表。它不会指向数组的数据缓冲区或其中的元素。
有连接的numpy数组与编译代码和使用数组数据缓冲区的C数组。 cython
是常见问题。关于numpy的C API还有一个完整的文档部分。我对pbind
了解一切。如果它需要一个列表界面,它可能不是最好的。
当我使用timeit
进行tolist()
测试时,它看起来并不那么昂贵。
=======================
但是看pybind11
github,我发现了numpy
的一些引用,这个
http://pybind11.readthedocs.io/en/latest/advanced.html#numpy-support
文档页面。它支持缓冲协议和numpy数组。因此,您不必经历tolist
步骤。
#include <pybind11/numpy.h>
void f(py::array_t<double> array);