在套接字上发送多维numpy数组

时间:2014-10-15 07:39:12

标签: python arrays numpy multidimensional-array

美好的一天,

我已经搜索了这个,但没有想出任何回复。我希望在套接字上发送一个多维的numpy数组。因此,我决定将其转换为字符串:

但是,它会破坏数组的表示形式:

>>> import numpy as np
>>> x = np.array([[0, 1], [2, 3]])
>>> xstring = x.tostring()
>>> print xstring

>>> print x
[[0 1]
 [2 3]]
>>> print xstring

>>> nparr = np.fromstring(xstring, dtype=np.uint8)
>>> print nparr
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0]

无论如何我可以以某种方式转换为字符串,保存它的维度吗?

3 个答案:

答案 0 :(得分:8)

试试这个例子: -

import socket
import numpy as np
from cStringIO import StringIO

class numpysocket():
    def __init__(self):
        pass

    @staticmethod
    def startServer():
        port=7555
        server_socket=socket.socket() 
        server_socket.bind(('',port))
        server_socket.listen(1)
        print 'waiting for a connection...'
        client_connection,client_address=server_socket.accept()
        print 'connected to ',client_address[0]
        ultimate_buffer=''
        while True:
            receiving_buffer = client_connection.recv(1024)
            if not receiving_buffer: break
            ultimate_buffer+= receiving_buffer
            print '-',
        final_image=np.load(StringIO(ultimate_buffer))['frame']
        client_connection.close()
        server_socket.close()
        print '\nframe received'
        return final_image

    @staticmethod
    def startClient(server_address,image):
        if not isinstance(image,np.ndarray):
            print 'not a valid numpy image'
            return
        client_socket=socket.socket()
        port=7555
        try:
            client_socket.connect((server_address, port))
            print 'Connected to %s on port %s' % (server_address, port)
        except socket.error,e:
            print 'Connection to %s on port %s failed: %s' % (server_address, port, e)
            return
        f = StringIO()
        np.savez_compressed(f,frame=image)
        f.seek(0)
        out = f.read()
        client_socket.sendall(out)
        client_socket.shutdown(1)
        client_socket.close()
        print 'image sent'
        pass

在此模型中,客户端将多维ndarray发送到服务器。 startServer()和startClient()有两个函数。 startServer不带参数,但startClient需要服务器地址以及ndarray作为参数。 首先启动Server,然后启动客户端。 只有在收到客户端的关闭消息后,服务器才会从缓冲区开始读取。

答案 1 :(得分:4)

实际上,.tostring仅返回原始数据。这意味着你还需要发送数组的形状和dtype,如果这些在另一方面是未知的。

使用Pickle序列化数组可能更容易:

import numpy as np
from cPickle import dumps, loads

x = np.array([[1, 2],[3, 4]], np.uint8)
print loads(dumps(x))
# [[1 2]
#  [3 4]]

虽然对于非常小的数组,大小开销可能很大:

print len(x.tostring()), len(dumps(x))
# 4 171

有关使用Pickle的更多信息,see here.

答案 2 :(得分:0)

对于使用XML-RPC的ajsp答案,这是一个临时的答案。

在服务器端,当您转换数据时,请使用以下命令将numpy数据转换为字符串: '。tostring()'方法。这会将numpy ndarray编码为字节字符串。在客户端,当您接收到数据时,请使用'。fromstring()'方法对其进行解码。为此,我编写了两个简单的函数。希望这会有所帮助。

  1. ndarray2str-将numpy ndarray转换为字节字符串。
  2. str2ndarray-将二进制str转换回numpy 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

注意:这种方法的唯一问题是,发送大型numpy数组时XML-RPC的速度非常慢。我花了大约4秒钟的时间为我发送和接收了一个(10,500,500,3)大小的numpy数组。

我正在使用python 3.7.4。