首页 > 解决方案 > 如何附加腌制熊猫数据框的块

问题描述

我在我的服务器上腌制了一个熊猫数据框,我通过套接字连接发送它,我可以接收数据,但我似乎无法将数据块一起附加到原始数据框格式,这就是我的全部努力实现!我有一种感觉,因为 data = [],它变成了一个列表,但我尝试了一个空的 pd Dataframe 并且没有用,所以我有点迷失了如何附加这些价值观

    data = []
    FATPACKET = 0
    bytelength = self.s.recv(BUFFERSIZE)
    length = int(pickle.loads(bytelength))
    print(length)
    ammo = 0

    while True:
        print("Getting Data....")
        packet = self.s.recv(1100)
        FATPACKET = int(sys.getsizeof(packet))
        ammo += FATPACKET
        print(str(FATPACKET) + '  Got this much of data out of '   +str(length))
        print("Getting Data.....")
        data.append(packet)
        print(ammo)
        if not ammo > length:
            break
    print(data)
    unpickled = pickle.loads(data)
    self.s.close()
    print("Closing Connection!")
    print(unpickled)

当我尝试这段代码时,我经常遇到这个

TypeError:需要一个类似字节的对象,而不是“列表”

或者我遇到这个

_pickle.UnpicklingError: 无效的加载键,'\x00'

这是我腌制数据框的前几个数字对不起,这是我第一次搞乱泡菜模块,所以我不是很了解

标签: python-3.xpandassocketspickle

解决方案


如果我们也能准确地看到您在发送端所做的事情,那将会有所帮助。但是,很明显你有几个问题。

首先,在 initialrecv中,很明显您打算只获取用于编码剩余字节长度的初始 pickle 对象。但是,这也recv 可能会收到剩余字节的初始段(甚至所有剩余字节,具体取决于它的大小)。那么你应该给最初的pickle.loads多少呢?

您最好创建一个固定长度的字段来包含剩余数据的大小。这通常是通过struct模块完成的。在发送方:

import struct
# Pickle the data to be sent
data = pickle.dumps(python_obj)
data_len = len(data)
# Pack data length into 4 bytes, encoded in network byte order
data_len_to_send = struct.pack('!I', data_len)  
# Send exactly 4 bytes (due to 'I'), then send data
conn.sendall(data_len_to_send)
conn.sendall(data)

在接收端,正如例外所说,pickle.loads采用字节字符串而不是列表。所以解决这个问题的一部分是在调用之前将所有列表元素连接成一个字节字符串loads

unpickled = pickle.loads(b''.join(data))

接收方的其他问题:用于len(packet)获取缓冲区大小。sys.getsizeof提供bytes对象使用的内部内存,其中包括未指定的解释器开销,这不是您在这里需要的。

之后,您应该做的第一件事是检查指示流结束(或什至)的recv空缓冲区。例如,如果发件人在完成发送之前被杀死(或者网络链接断开,或者发件人方面的一些错误等),就会发生这种情况。否则,如果连接过早结束,您的程序将永远无法到达,因此它将处于非常紧密的无限循环中。len(packet) == 0packet == ''not packetbreak

所以,你完全可以做这样的事情:

# First, obtain fixed-size content length
buf = b''
while len(buf) < 4:
    tbuf = recv(4 - len(buf))
    if tbuf == '':
        raise RuntimeError("Lost connection with peer") 
    buf += tbuf

# Decode (unpack) length (note that unpack returns an array)
len_to_recv = struct.unpack('!I', buf)[0]

data = []
len_recved = 0
while len_recvd < len_to_recv:
    buf = self.s.recv(min(len_to_recv - len_recvd, BUFFERSIZE))
    if buf == '':   
        raise RuntimeError("Lost connection with peer") 
    data.append(buf)
    len_recvd += len(buf)

unpickled_obj = pickle.loads(b''.join(data))

编辑:移动括号


推荐阅读