Как добавить кусочки маринованных панд в DataFrame - PullRequest
0 голосов
/ 17 января 2019

Я выбрал фрейм данных pandas на своем сервере, и я отправляю его через сокетное соединение, и я могу получать данные, но я не могу добавить фрагменты данных обратно в исходный формат Dataframe, который все Я пытаюсь достичь! У меня такое ощущение, что я добавляю его в список из-за данных = [], но я попробовал пустой DataFrame для pd, и это не сработало, так что я немного растерялся относительно того, как плохо я добавляю эти данные. значения

    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'

это первая пара цифр моего маринованного Dataframe, извините, это мой первый раз, когда я возился с модулем маринования, поэтому я не очень хорошо осведомлен

1 Ответ

0 голосов
/ 17 января 2019

Было бы полезно, если бы мы могли точно видеть, что вы делаете на отправляющей стороне. Однако очевидно, что у вас есть несколько проблем.

Во-первых, в начальном recv очевидно, что вы намеревались получить только начальный объект 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) == 0 или packet == '' или not packet даже). Это может произойти, например, если отправитель был убит до завершения отправки (или сбой сетевого соединения, или какая-то ошибка на стороне отправителя и т. Д.). В противном случае, если соединение заканчивается преждевременно, ваша программа никогда не достигнет 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))

РЕДАКТИРОВАТЬ: перемещенные скобки

...