【问题标题】:Convert C++ vector to numpy array in Cython without copying [duplicate]在 Cython 中将 C++ 向量转换为 numpy 数组而不复制 [重复]
【发布时间】:2026-01-23 11:25:02
【问题描述】:

有一个 C++ 函数可以返回一个浮点向量。如何在不复制的情况下将此向量转换为 NumPy 数组?现在我正在这样做:

cdef np.ndarray arr = np.ascontiguousarray(cpp_vector, dtype=np.float)
return arr

但这在大型向量上工作得非常慢(假设发生复制)。

【问题讨论】:

  • 问题是,你能确保 cpp_vector 的存活时间足够长吗?否则你会在 numpy-array 中得到悬空指针。
  • 请注意,C++ 标准不保证使用 IEEE 754 格式,即使大多数(所有?)编译器都是这种情况。这里不应该是个问题吗?
  • 获得缓冲区接口后,您可以使用docs.scipy.org/doc/numpy-1.17.0/reference/generated/… 获得一个 numpy 数组而无需复制。如果缓冲区接口太多,您可以从第一个链接稍微更改 memory-nanny-approach 以使用 std::vector。顺便说一句,使用 std::move (C++11) 或 std::swap (也是 C++98),您可以更改 std::vector 中数据的所有权。

标签: python c++ cython numpy-ndarray


【解决方案1】:

将向量转换为浮点数组并告诉 numpy 应该可以解决问题。

cdef float[::1] arr = <float [:cpp_vector.size()]>cpp_vector.data()
return arr

# arr is of type Memoryview. To cast into Numpy:
np_arr = np.asarray(arr)

[::1] 表示法是指Typed MemoryView (link)。在链接中,您将获得更多示例。我们还使用np.asarray 将 tne MemoryView 转换为 numpy 数组(在 SO Here 中回答)。这个想法是告诉 Cython 以预定义的格式查看该内存空间,避免任何复制。从名为 Coertion 到 Numpy 的文档的 this section 扩展:

Memoryview(和数组)对象可以强制转换为 NumPy ndarray,无需 必须复制数据。你可以例如做:

cimport numpy as np
import numpy as np

numpy_array = np.asarray(<np.float_t[:10, :10]> my_pointer)

当然, 你不限于使用 NumPy 的类型(例如 np.float_ 这里),你可以使用任何可用的类型。

来源: https://cython.readthedocs.io/en/latest/src/userguide/memoryviews.html#coercion-to-numpy

【讨论】:

  • 我收到Pointer base type does not match cython.array base type。我认为这是因为向量具有纯 C float,但我正在尝试将其转换为 np.float_t。如何解决这个问题?
  • 纯 C float 可能等效于 np.float32(32 位)而不是 np.float_(64 位)。玩一点输出类型,你应该得到它。
  • 注意:请在正确时修改或评论我的答案!我们都想学习如何去做。
  • 我试过cdef float[::1] arr = &lt;float [:cpp_vector.size()]&gt;cpp_vector.data(); return arr,它返回&lt;MemoryView of 'array' object&gt;(没关系)。如果我这样做return np.asarray(arr) 我会得到Segmentation fault...
  • 这存在内存管理问题 - 它不会将向量的生命周期与 numpy 数组的生命周期联系起来
最近更新 更多