私はこれが本当にサポートされているとは思わないが、あなたはこれをしたいならば、最良の方法は、使用することをおそらくstructs
のmemoryviews(numpysカスタムdtypesと互換性のある):
import numpy as np
cdef packed struct Pair1: # packed ensures it matches custom numpy dtypes
# (but probably doesn't matter here!)
double x
double y
# pair 1 matches arrays of this dtype
pair_1_dtype = [('x',np.float64), ('y',np.float64)]
cdef packed struct Pair2:
double data[2]
pair_2_dtype = [('data',np.float64, (2,))]
def pair_func1(Pair1[::1] x):
# do some very basic work
cdef Pair1 p
cdef Py_ssize_t i
p.x = 0; p.y = 0
for i in range(x.shape[0]):
p.x += x[i].x
p.y += x[i].y
return p # take advantage of auto-conversion to a dict
def pair_func2(Pair2[::1] x):
# do some very basic work
cdef Pair2 p
cdef Py_ssize_t i
p.data[0] = 0; p.data[1] = 0
for i in range(x.shape[0]):
p.data[0] += x[i].data[0]
p.data[1] += x[i].data[1]
return p # take advantage of auto-conversion to a dict
と、それを呼び出す方法をお見せするための機能:
def call_pair_funcs_example():
# generate data of correct dtype
d = np.random.rand(100,2)
d1 = d.view(dtype=pair_1_dtype).reshape(-1)
print(pair_func1(d1))
d2 = d.view(dtype=pair_2_dtype).reshape(-1)
print(pair_func2(d2))
私が行っているしたい事はある:
正常にコンパイルが、私はnumpyのからそれを変換する任意の方法を見つけることができませんでした
ctypedef double[2] Pair3
def pair_func3(Pair3[::1] x):
# do some very basic work
cdef Pair3 p
cdef Py_ssize_t i
p[0] = 0; p[1] = 0
for i in range(x.shape[0]):
p[0] += x[i][0]
p[1] += x[i][1]
return p # ???
。あなたがこのバージョンを動作させる方法を考え出すことができれば、それは最も洗練されたソリューションだと思います。
これらのソリューションのパフォーマンス上の利点はわかりません。あなたの最善の動きはおそらく、後続の次元がメモリ内で連続していることをCythonに伝えることです(例えばdouble [:,::1]
)。
質問:numpy配列のデータを 'float [2] *'に変換するにはどうすればよいですか? – user1447257
@ user1447257これで何を達成したいですか?パフォーマンスのために静的な形状の配列が必要だったようです。しかし、これがコード内の文法的な砂糖であるならば、汎用メモリビュー構文 'float [:、:]'を使うこともできます。 'numpy'配列は動的なので、データを明示的にコピーしない限り、' float [2] * 'に束縛されません。 – romeric
キャッシュミスを少なくするために、私のコードはエントリを何度も繰り返し処理するので、私は連続した配列にコピーします。ポインタを完全に線形にインクリメントできるので、 'float [2] *'データ型へのキャストはパフォーマンスを少し向上させるかもしれないと私は考えていました。 – user1447257