cythonのポインタ変数の要素数はどのようにして決められますか?私はCの中で、という変数をポインタが指していると、sizeof(ptr)/sizeof(int)
のように見えます。しかし、それはcythonでは動作しないようです。例えば。私はそうのような単一のポインタに二つのメモリビューに参加しようとしたとき:cython - ポインタ変数の項目数を調べる
from libc.stdlib cimport malloc, free
cdef int * join(int[:] a, int[:] b):
cdef:
int n_a = a.shape[0]
int n_b = b.shape[0]
int new_size = n_a + n_b
int *joined = <int *> malloc(new_size*sizeof(int))
int i
try:
for i in range(n_a):
joined[i] = a[i]
for i in range(n_b):
joined[n_a+i] = b[i]
return joined
finally:
free(joined)
@cython.cdivision(True)
def join_memviews(int[:] n, int[:] m):
cdef int[:] arr_fst = n
cdef int[:] arr_snd = m
cdef int *arr_new
cdef int new_size
arr_new = join(arr_fst,arr_snd)
new_size = sizeof(arr_new)/sizeof(int)
return [arr_new[i] for i in range(new_size)]
Pythonスクリプトからjoin_memviews
を呼び出すときに、私は、例えば、望ましい結果を得ることはありません。
# in python
a = np.array([1,2])
b = np.array([3,4])
a_b = join_memviews(a,b)
私も使ってみましたタイプ
DTYPE = np.int
ctypedef np.int_t DTYPE_t
sizeof()
内の引数として、どちらも機能しませんでした。
を編集します。ポインタ変数の処理が明らかに私を不注意にしていました。次のように問題はないと思います(慎重なアプローチではないかもしれませんが)。
cdef int * join(int[:] a, int[:] b, int new_size):
cdef:
int *joined = <int *> malloc(new_size*sizeof(int))
int i
for i in range(n_a):
joined[i] = a[i]
for i in range(n_b):
joined[n_a+i] = b[i]
return joined
def join_memviews(int[:] n, int[:] m):
cdef int[:] arr_fst = n
cdef int[:] arr_snd = m
cdef int *arr_new
cdef int new_size = n.shape[0] + m.shape[0]
try:
arr_new = join(arr_fst,arr_snd, new_size)
return [arr_new[i] for i in range(new_size)]
finally:
free(arr_new)
これらの説明をいただきありがとうございます。 'try-finally'の部分に関しては、' joined'が解放される前に関数が返す変数にコピーされると考えました。しかし、私はチェックしていないので、警告に感謝します。私はそれが合理的なアプローチではないかもしれませんが、適切に動作するはずのコードを編集します。 – user3820991
編集がうまくいくように見えます。しかし、私はnumpyを使って同じタスクを実行したいと思うでしょう: 'np.concatenate((a、b))' – DavidW
もちろん、2つの配列を結合したいだけならnumpyを使います。私はcythonで実装されたより大きなタスクの中でメモリビューに参加する必要があります。それはかなり起こり、私は[ここ](https://stackoverflow.com/questions/18462785/what-is-the-recommended-way-of-allocating-memory-for-a-typed-memory- view/21054369#21054369)、mallocのアプローチは反復処理を通した迅速な初期化とアクセスを提供するので、私はそのように試してみたかったのです。それでも、私はおそらく最初に、プロファイルよりもセーブしてみるべきです。 – user3820991