[英]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.