美好的一天,
我已经搜索了这个,但没有想出任何回复。我希望在套接字上发送一个多维的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]
无论如何我可以以某种方式转换为字符串,保存它的维度吗?
答案 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()'方法对其进行解码。为此,我编写了两个简单的函数。希望这会有所帮助。
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。