You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NumPy数组ndarray.data与ndarray.ctypes.data的区别探究

问题:NumPy数组的.data与.ctypes.data区别解析

我有一个C数组想要在Python中使用,通过pybind11将该C数组暴露为原始内存缓冲区,C++代码如下:

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

namespace py = pybind11;

py::memoryview create_cpp_owned()
{
  const double *dynamic_c_array = new double[4]{0, -1.2, 3.24, 9.0};
  std::cout << "Memory address of the C array: " << dynamic_c_array;
  return py::memoryview::from_memory(dynamic_c_array, sizeof(double) * 4);
}

随后在Python中调用create_cpp_owned函数(raw_data为memoryview对象):

print('Creating a direct accessor to a C++ buffer (memory owned by C++)...')
raw_data = create_cpp_owned()
print(f'Address of the raw data: {raw_data}') # or: print(hex(id(raw_data)))
np_view = np.frombuffer(raw_data, dtype=np.float64)
print(f'NumPy view on this data: "np_view" = {np_view}')
print(f'Address of "np_view": {hex(np_view.ctypes.data)}')
print(f'Note that np_view.data does not return the same address: {np_view.data}')
print(f'Python does not own the memory: np_view.flags["OWNDATA"] = {np_view.flags["OWNDATA"]}')

运行输出如下:

Creating a direct accessor to a C++ buffer (memory owned by C++)...
Memory address of the C array: 0x55af59d39590
Address of the raw data: <memory at 0x14a9af19f640>
NumPy view on this data: "np_view" = [ 0.   -1.2   3.24  9.  ]
Address of "np_view": 0x55af59d39590
Note that np_view.data does not return the same address: <memory at 0x14a99f3aa280>
Python does not own the memory: np_view.flags["OWNDATA"] = False

可以看到np_view.data未返回底层C数组的正确地址,而np_view.ctypes.data返回了。那么对于NumPy数组来说,.data和.ctypes.data到底分别代表什么?


回答

1. np.ndarray.data

  • data属性返回的是Python memoryview对象,它是对NumPy数组底层内存的包装视图。
  • 输出中的<memory at 0x14a99f3aa280>是这个memoryview对象本身在Python堆中的地址,而非底层C数组的内存地址。
  • 该memoryview的作用是让Python代码通过缓冲区协议访问数组数据,但它本身是独立的Python对象,有自己的内存空间。

2. np.ndarray.ctypes.data

  • ctypes.data返回的是底层数据缓冲区的原始C风格内存地址(整数类型),直接对应C++中分配的数组内存(比如示例中的0x55af59d39590)。
  • 它本质是直接获取NumPy数组底层指针指向的起始地址,是数据实际存储的位置。
  • 当NumPy数组是外部内存的视图(如通过np.frombuffer创建的非自有数据数组),这个属性能准确拿到外部数据的真实地址。

关键区别总结

  • .data是Python层面的内存视图对象,显示的是对象自身的地址,而非数据的存储地址。
  • .ctypes.data直接返回底层数据的C内存地址,是数据实际存放的位置。

内容的提问来源于stack exchange,提问作者Zoltan Csati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:33:11