2017-09-15 4 views
2

J'ai un code cython qui prend un 2d numpy.ndarray de données (M) et un numpy.ndarray d'index (Ixs). Il parcourt les entrées de Ixs et utilise les valeurs ix de Ixs pour indexer les colonnes de M. Voir le code ci-dessous:Une vue en mémoire Cython des index doit-elle être de type Py_ssize_t ou int?

def foo(double[:, ::1] M, int[:, ::1] Ixs): 
    cdef int rows = M.shape[0] 
    cdef int cols = M.shape[1] 
    cdef Py_ssize_t c, r 
    for c in range(rows): 
     for r in range(cols): 
      ix = Ixs[c, r] 
      dosomething(M[c, ix]) 

Je sais que je suis censé utiliser Py_ssize_t comme un type d'index (je l'ai lu est d'accueillir pour les architectures 64 bits), mais en ce moment je suis en utilisant une vue de mémoire de type int ... Dans ce cas, je ne vois pas un moyen de créer un numpy.ndarray de Py_ssize_t de sorte que ix soit Py_ssize_t.

Quelle est la bonne façon d'écrire ce code cython? Y at-il un problème à utiliser int?

Répondre

3

Une chose à noter, vous voulez taper ix

Votre code comme écrit fonctionnera OK, M[c, ix] sera ix jeté d'un int à Py_ssize_t, qui doit toujours être une conversion sûre.

Cela dit, vous pouvez et devriez probablement avoir votre table d'indexeur de Py_ssize_t. Le correspondant de type numpy est np.intp

https://docs.scipy.org/doc/numpy-1.13.0/user/basics.types.html

+0

Alors disons que je l'ai jeté en python à np.intp ('Ixs = Ixs.atype (np.intp)') alors je récrire cette fonction: 'def foo (double [:, :: 1] M, Py_ssize_t [:, :: 1] Ixs): 'juste? – Gioelelm

+0

Oui, bien que idéalement 'Ixs' tapé intp à la création pour éviter la distribution. – chrisb

+0

Bien sûr, mais dans mon cas ce sera une sortie d'une fonction d'apprentissage de scikit. – Gioelelm