141 votes

Conversion de type d’un tableau NumPy sur place

Étant donné un tableau NumPy d' int32, comment puis-je convertir float32 en place? Donc en gros, je voudrais faire

a = a.astype(numpy.float32)

sans copier le tableau. Il est grand.

La raison pour cela est que j'ai deux algorithmes pour le calcul de l' a. L'un d'eux retourne un tableau d' int32, l'autre retourne un tableau d' float32 (et c'est inhérent à ces deux algorithmes différents). Tous les autres calculs supposent que a est un tableau d' float32.

Actuellement je fais la conversion en une fonction C appelé via ctypes. Est-il un moyen de le faire en Python?

169voto

Vikas Points 687
<pre><code></code><p>astype NumPy possède un indicateur de copie. Pourquoi est-ce que nous ne devrions pas utiliser il ?</p></pre>

118voto

unutbu Points 222216

Qu’en est-il :

(Pour afficher que la conversion était sur place) :

14voto

Paul Points 13042

Vous pouvez modifier le type du tableau sans avoir à les convertir comme ceci:

a.dtype = numpy.float32

mais d'abord, vous devez changer tous les entiers de quelque chose qui va être interprété comme correspondant à flotteur. Un très lente façon de le faire serait d'utiliser python struct module comme ceci:

def toi(i):
    return struct.unpack('i',struct.pack('f',float(i)))[0]

...appliquée à chaque membre de votre groupe.

Mais peut-être un moyen plus rapide serait d'utiliser numpy est ctypeslib outils (dont je suis pas familier avec)

- edit -

Depuis ctypeslib n'a pas l'air de travailler, alors je voudrais procéder à la conversion avec la typique numpy.astype méthode, mais de procéder à des tailles de bloc à l'intérieur de vos limites de la mémoire:

a[0:10000] = a[0:10000].astype('float32').view('int32')

...puis changer le dtype lorsque vous avez terminé.

Voici une fonction qui accomplit la tâche pour tout compatible dtypes (ne fonctionne que pour les dtypes avec les mêmes éléments de taille) et les poignées de manière arbitraire en forme des tableaux avec de l'utilisateur-contrôle de la taille de bloc:

import numpy

def astype_inplace(a, dtype, blocksize=10000):
    oldtype = a.dtype
    newtype = numpy.dtype(dtype)
    assert oldtype.itemsize is newtype.itemsize
    for idx in xrange(0, a.size, blocksize):
        a.flat[idx:idx + blocksize] = \
            a.flat[idx:idx + blocksize].astype(newtype).view(oldtype)
    a.dtype = newtype

a = numpy.random.randint(100,size=100).reshape((10,10))
print a
astype_inplace(a, 'float32')
print a

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X