web-dev-qa-db-fra.com

Convertir un numpy.ndarray en chaîne (ou en octets) et le reconvertir en numpy.ndarray

J'ai un petit problème ici,

J'essaie de convertir un numpy.ndarray en chaîne, je l'ai déjà fait comme ceci:

randomArray.tostring()

Cela fonctionne, mais je me demande si je peux le reconvertir en numpy.ndarray.

Quelle est la meilleure façon de faire cela?

J'utilise numpy 1.8.1

Contexte: L'objectif est d'envoyer le numpy.ndarray sous la forme d'un message dans rabbitmq (bibliothèque pika)

26
Ampo

Vous pouvez utiliser la méthode fromstring () pour cela:

arr =np.array([1,2,3,4,5,6])
ts = arr.tostring()
print np.fromstring(ts,dtype=int)

>>>[1 2 3 4 5 6]

Désolé pour la réponse courte, pas assez de points pour commenter. N'oubliez pas d'indiquer les types de données ou vous vous retrouverez dans un monde de douleur.

23
ajsp

Si vous utilisez tostring, vous perdez des informations sur la forme et le type de données:

>>> import numpy as np
>>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> s = a.tostring()
>>> aa = np.fromstring(a)
>>> aa
array([  0.00000000e+000,   4.94065646e-324,   9.88131292e-324,
         1.48219694e-323,   1.97626258e-323,   2.47032823e-323,
         2.96439388e-323,   3.45845952e-323,   3.95252517e-323,
         4.44659081e-323,   4.94065646e-323,   5.43472210e-323])
>>> aa = np.fromstring(a, dtype=int)
>>> aa
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> aa = np.fromstring(a, dtype=int).reshape(3, 4)
>>> aa
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Cela signifie que vous devez envoyer les métadonnées avec les données au destinataire. Pour échanger des objets à cohérence automatique, essayez cPickle:

>>> import cPickle
>>> s = cPickle.dumps(a)
>>> cPickle.loads(s)
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
21
simleo

Imaginez que vous ayez un tableau d'entiers numpy (cela fonctionne avec d'autres types mais vous avez besoin d'une légère modification). Tu peux le faire:

a = np.array([0, 3, 5])
a_str = ','.join(str(x) for x in a) # '0,3,5'
a2 = np.array([int(x) for x in a_str.split(',')]) # np.array([0, 3, 5])

Si vous avez un tableau de float, veillez à remplacer int par float à la dernière ligne.

Vous pouvez également utiliser la méthode __repr__(), qui aura l'avantage de fonctionner pour les tableaux multidimensionnels:

from numpy import array
numpy.set_printoptions(threshold=numpy.nan)
a = array([[0,3,5],[2,3,4]])
a_str = a.__repr__() # 'array([[0, 3, 5],\n       [2, 3, 4]])'
a2 = eval(a_str) # array([[0, 3, 5],
                 #        [2, 3, 4]])
8
Julien Spronck

Ceci est une réponse légèrement improvisée à la réponse ajsp en utilisant XML-RPC.

Sur le serveur, lorsque vous convertissez les données, convertissez les données numpy en chaîne à l'aide de la méthode '. Tostring ()'. Ceci code la chaîne numpy ndarray en octets. Du côté client, lorsque vous recevez les données, décodez-les en utilisant la méthode '. Fromstring ()'. J'ai écrit deux fonctions simples pour cela. J'espère que c'est utile.

  1. ndarray2str - Convertit numpy ndarray en chaîne d'octets.
  2. str2ndarray - Convertit la chaîne binaire en numpy ndarray.
    def ndarray2str(a):
        # Convert the numpy array to string 
        a = a.tostring()

        return a

Du côté du destinataire, les données sont reçues sous la forme d'un objet 'xmlrpc.client.Binary'. Vous devez accéder aux données en utilisant '. Data'.

    def str2ndarray(a):
        # Specify your data type, mine is numpy float64 type, so I am specifying it as np.float64
        a = np.fromstring(a.data, dtype=np.float64)
        a = np.reshape(a, new_shape)

        return a

Note: Le seul problème avec cette approche est que XML-RPC est très lent lors de l'envoi de tableaux numpy volumineux. Il m'a fallu environ 4 secondes pour envoyer et recevoir un tableau numpy de taille (10, 500, 500, 3) pour moi.

J'utilise python 3.7.4.

1
Sudheer Raja