Преобразуйте numpy.ndarray в строку (или байты) и преобразуйте ее обратно в numpy.ndarray

У меня здесь небольшая проблема,

Я пытаюсь преобразовать numpy.ndarray в строку, я уже сделал это вот так:

randomArray.tostring()

Это работает, но мне интересно, могу ли я преобразовать его обратно в numpy.ndarray.

Какой лучший способ сделать это?

Я использую numpy 1.8.1

Контекст: Цель состоит в том, чтобы отправить numpy.ndarray как сообщение в rabbitmq (библиотека pika)

Ответ 1

Вы можете использовать метод fromstring() для этого:

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

>>>[1 2 3 4 5 6]

Извините за короткий ответ, недостаточно очков для комментариев. Не забудьте указать типы данных, иначе вы окажетесь в мире боли.

Ответ 2

Если вы используете tostring, вы теряете информацию о форме и типе данных:

>>> 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]])

Это означает, что вам необходимо отправить метаданные вместе с данными получателю. Чтобы обменять автоматически согласованные объекты, попробуйте cPickle:

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

Ответ 3

Представьте, что у вас есть массив numpy целых чисел (он работает с другими типами, но вам нужна небольшая модификация). Вы можете сделать это:

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])

Если у вас есть массив float, обязательно замените int на float в последней строке.

Вы также можете использовать метод __repr__(), который будет иметь преимущество для работы с многомерными массивами:

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]])

Ответ 4

Это слегка импровизированный ответ на ajsp ответ с использованием XML-RPC.

На стороне сервера, когда вы преобразуете данные, преобразуйте пустые данные в строку, используя метод .tostring(). Это кодирует numy ndarray как строку байтов. На стороне клиента, когда вы получаете данные, декодируйте их, используя метод '.fromstring()'. Я написал две простые функции для этого. Надеюсь, это полезно.

  1. ndarray2str - конвертирует numy ndarray в строку байтов.
  2. str2ndarray - преобразует двоичный str обратно в numy ndarray.
    def ndarray2str(a):
        # Convert the numpy array to string 
        a = a.tostring()

        return a

На стороне получателя данные принимаются как объект 'xmlrpc.client.Binary'. Вам необходимо получить доступ к данным с помощью.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

Примечание: Единственная проблема этого подхода в том, что XML-RPC очень медленный при отправке больших массивов. Мне потребовалось около 4 секунд, чтобы отправить и получить массив данных размером (10, 500, 500, 3) для меня.

Я использую Python 3.7.4.

Ответ 5

Представьте, что у вас есть массив текстов, как в мессенджере

 >>> stex[40]
 array(['Know the famous thing ...

и вы хотите получить статистику из корпуса (текст col = 11), сначала вы должны получить значения из фрейма данных (df5), а затем объединить все записи в один корпус:

 >>> stex = (df5.ix[0:,[11]]).values
 >>> a_str = ','.join(str(x) for x in stex)
 >>> a_str = a_str.split()
 >>> fd2 = nltk.FreqDist(a_str)
 >>> fd2.most_common(50)