Как найти dtype для numpy recarray при загрузке из байтов, если оригинальный dtype неизвестен - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь создать пустой массив из некоторых данных буфера, где важно сохранить имена столбцов, которые присутствовали при преобразовании массива в объект байтов.

Короткий пример, иллюстрирующий, чтоЯ хочу сделать:

import pandas as pd
import numpy as np

asDF = pd.DataFrame(np.random.random((5,5)),index=np.linspace(-10,0,5),columns=np.linspace(0,1,5)) # Just need a quick way to make a record array with column titles
DFasRec = asDF.to_records()
RecAsStr = DFasRec.tobytes()
# Now I want to get my DFasRec back
recarr = np.frombuffer(RecAsStr)
asArr = np.rec.array(recarr)

Как примечание, я могу предположить, что и данные, и заголовки столбцов являются числами с плавающей точкой. (Это позиционные данные, поэтому заголовки столбцов и первый столбец данных представляют координаты x / y)

И это работает - однако при этом заголовки / dtypes столбцов теряются. Я могу восстановить исходный массив, если я знаю исходные dtypes. IE:

recarr = np.frombuffer(RecAsStr,dtype=DFasRec.dtype)

но я не могу предположить, что у меня есть эта информация. Есть ли способ получить эти данные в процессе загрузки или встроить их во время преобразования tobytes(), чтобы я мог извлечь их позже? Как примечание, этот процесс преобразования происходит во время поездки в / из базы данных SQLite, поэтому у меня нет возможности сохранить файл вместе с данными с помощью dtypes и т. Д.

1 Ответ

0 голосов
/ 29 октября 2019

Итак, ваш фрейм данных:

In [129]: asDF                                                                  
Out[129]: 
           0.00      0.25      0.50      0.75      1.00
-10.0  0.161848  0.381348  0.274634  0.207572  0.620306
-7.5   0.397057  0.291996  0.641298  0.091828  0.143980
-5.0   0.571381  0.933822  0.323190  0.979055  0.749772
-2.5   0.389751  0.907248  0.971688  0.395117  0.135636
 0.0   0.860973  0.614596  0.302016  0.991079  0.498841

, а форма повторного массива включает индексы строк в качестве дополнительного поля (это необязательно):

In [130]: DFasRec                                                               
Out[130]: 
rec.array([(-10. , 0.16184848, 0.38134831, 0.27463366, 0.20757185, 0.62030599),
           ( -7.5, 0.39705653, 0.291996  , 0.64129751, 0.09182781, 0.14398041),
           ( -5. , 0.57138102, 0.9338216 , 0.32318977, 0.97905532, 0.74977176),
           ( -2.5, 0.38975072, 0.90724842, 0.97168799, 0.39511716, 0.13563595),
           (  0. , 0.86097342, 0.61459591, 0.30201566, 0.99107931, 0.49884148)],
          dtype=[('index', '<f8'), ('0.0', '<f8'), ('0.25', '<f8'), ('0.5', '<f8'), ('0.75', '<f8'), ('1.0', '<f8')])
In [131]: DFasRec.dtype.names                                                   
Out[131]: ('index', '0.0', '0.25', '0.5', '0.75', '1.0')

имена столбцов находятся в dtype, но не в самих данных массива.

С простым arr1 = np.frombuffer(RecAsStr):

In [132]: arr1                                                                  
Out[132]: 
array([-10.        ,   0.16184848,   0.38134831,   0.27463366,
         0.20757185,   0.62030599,  -7.5       ,   0.39705653,
         0.291996  ,   0.64129751,   0.09182781,   0.14398041,
        -5.        ,   0.57138102,   0.9338216 ,   0.32318977,
         0.97905532,   0.74977176,  -2.5       ,   0.38975072,
         0.90724842,   0.97168799,   0.39511716,   0.13563595,
         0.        ,   0.86097342,   0.61459591,   0.30201566,
         0.99107931,   0.49884148])

Это всего лишь 1d массив;это работает (пока), потому что все поля были плавающими, а тип загрузки по умолчанию - float. Этот буфер не имеет информации о dtype!

Reshape позволяет нам восстановить 2d массив со значениями индекса строки.

In [133]: arr1.reshape(-1,6)                                                    
Out[133]: 
array([[-10.        ,   0.16184848,   0.38134831,   0.27463366,
          0.20757185,   0.62030599],
       [ -7.5       ,   0.39705653,   0.291996  ,   0.64129751,
          0.09182781,   0.14398041],
       [ -5.        ,   0.57138102,   0.9338216 ,   0.32318977,
          0.97905532,   0.74977176],
       [ -2.5       ,   0.38975072,   0.90724842,   0.97168799,
          0.39511716,   0.13563595],
       [  0.        ,   0.86097342,   0.61459591,   0.30201566,
          0.99107931,   0.49884148]])

Этот маршрут bytes не хранит никакой информации dtype,Я думаю, что это должно быть сохранено (или восстановлено) отдельно.

Например:

In [146]: str(DFasRec.dtype)                                                    
Out[146]: "(numpy.record, [('index', '<f8'), ('0.0', '<f8'), ('0.25', '<f8'), ('0.5', '<f8'), ('0.75', '<f8'), ('1.0', '<f8')])"
In [147]: dt = np.dtype(eval(_))                                                
In [148]: dt                                                                    
Out[148]: dtype((numpy.record, [('index', '<f8'), ('0.0', '<f8'), ('0.25', '<f8'), ('0.5', '<f8'), ('0.75', '<f8'), ('1.0', '<f8')]))
In [149]: np.frombuffer(RecAsStr, dt)                 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...