[英]Convert ctypes object to numpy array
我正在尝试编写一个 ctypes 结构,以便可以轻松地将其转换为 numpy 数组并用于分配。 这是一个显示问题的简单示例:
from ctypes import Structure, c_double
import numpy as np
class Vec3d:
x = 1
y = 2
z = 3
def __array__(self, dtype):
return np.array([self.x, self.y, self.z])
class Vec3dS(Structure):
_fields_ = [("x", c_double), ("y", c_double), ("z", c_double)]
def __array__(self, dtype):
return np.array([self.x, self.y, self.z])
v = Vec3d()
vs = Vec3dS(1,2,3)
n = np.zeros((2,3))
n[0] = v
n[1] = vs
第一个赋值n[0]=v
有效,但第二个赋值 n n[1]=vs
无效。 Numpy 似乎能够将v
转换为 numpy 数组,但赋值最终失败,因为数组的数据类型错误:
TypeError: Cannot cast array data from dtype([('x', '<f8'), ('y', '<f8'), ('z', '<f8')]) to dtype('float64').
它与我使用的 dtype 相同
np.array(vs)
为什么在使用ctypes.Structure
时实施__array__
(我也试过__array_interface__
)不起作用? 我如何修改Vec3dS
class 以提示 numpy 如何将其转换为具有正确数据类型和值的 numpy 数组?
编辑:我怀疑ctypes.Structure
实现了优先于__array__
的 PEP 3118。 是否可以从 python 端覆盖它?
使用numpy.frombuffer
似乎效果很好。
v = Vec3d(1,2,3)
l = [1,2,3]
n = np.zeros((2,3))
n[0] = l
n[1] = np.frombuffer(v)
assert (n[0] == n[1]).all()
如果您使用np.zeros(2, dtype=Vec3dS)
而不是np.zeros((2,3))
那么您根本不需要在 ctypes 结构上使用__array__
:
from ctypes import Structure, c_double
import numpy as np
class Vec3d:
x = 1
y = 2
z = 3
def __array__(self, dtype):
return np.array(
(self.x, self.y, self.z),
dtype=[('x', np.double), ('y', np.double), ('z', np.double)])
class Vec3dS(Structure):
_fields_ = [("x", c_double), ("y", c_double), ("z", c_double)]
v = Vec3d()
vs = Vec3dS(1,2,3)
n = np.zeros(2, dtype=Vec3dS)
# note: since the array is 1d, we need `...` to prevent decay to scalars, which
# don't behave well with `__array__`
n[0, ...] = v
n[1, ...] = vs
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.