如何附加 pickled pandas DataFrame 的块

How to append chunks of a pickled pandas DataFrame

我在我的服务器上腌制了一个 pandas 数据帧,我正在通过套接字连接发送它,我可以接收数据,但我似乎无法将数据块追加到一起我正在努力实现的原始 Dataframe 格式!我有一种感觉,由于 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: 需要类似字节的对象,而不是 'list'

或者我运行进入这个

_pickle.UnpicklingError: 加载密钥无效,'\x00'

这是我的 pickle Dataframe 的前几位数字抱歉这是我第一次弄乱 pickle 模块所以我不是很了解

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

首先,在最初的 recv 中,很明显您打算只获取用于编码剩余字节长度的初始 pickle 对象。但是,recv 可能 也会收到剩余字节的初始段(甚至 all 剩余字节,具体取决于如何大)。那么你应该给初始 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 packet甚至)。例如,如果发件人在完成发送之前被杀死(或网络 link 出现故障,或发件人端出现某些错误等),就会发生这种情况。否则,如果连接过早结束,您的程序将永远不会到达 break,因此它将处于非常紧密的无限循环中。

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

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

编辑:移动括号