2016-02-03 3 views
5

Я хочу сохранить dataFrame с разными столбцами в файл hdf5 (найти отрывок с типами данных ниже).Хранение pandas DataFrame со смешанными данными и категорией в hdf5

In [1]: mydf 
Out [1]: 
endTime    uint32 
distance   float16 
signature   category 
anchorName  category 
stationList   object 

Перед преобразованием некоторых столбцов (подпись и AnchorName в моем отрывке выше), я использовал код как следующий, чтобы сохранить его (который работает довольно отлично):

path = 'tmp4.hdf5' 
key = 'journeys' 
mydf.to_hdf(path, key, mode='w', complevel=9, complib='bzip2') 

Но она не работает с категории а затем я попытался следующее:

path = 'tmp4.hdf5' 
key = 'journeys' 
mydf.to_hdf(path, key, mode='w', format='t', complevel=9, complib='bzip2') 

Он отлично работает, если удалить столбец stationList, где каждая запись представляет собой список строк. Но с этой колонкой я получил следующее исключение:

Cannot serialize the column [stationList] because 
its data contents are [mixed] object dtype 

0 Как мне улучшить код, чтобы получить фрейм данных? версия

панды: 0.17.1
питон версия: 2.7.6 (не может изменить его по причинам Compability)


edit1 (некоторые примеры кода):

import pandas as pd 

mydf = pd.DataFrame({'endTime' : pd.Series([1443525810,1443540836,1443609470]), 
        'distance' : pd.Series([454.75,477.25,242.12]), 
        'signature' : pd.Series(['ab','cd','ab']), 
        'anchorName' : pd.Series(['tec','ing','pol']), 
        'stationList' : pd.Series([['t1','t2','t3'],['4','t2','t3'],['t3','t2','t4']]) 
        }) 

# this works fine (no category) 
mydf.to_hdf('tmp_without_cat.hdf5', 'journeys', mode='w', complevel=9, complib='bzip2') 

for col in ['anchorName', 'signature']: 
    mydf[col] = mydf[col].astype('category') 

# this crashes now because of category data 
# mydf.to_hdf('tmp_with_cat.hdf5', 'journeys', mode='w', complevel=9, complib='bzip2') 

# switching to format='t' 
# this caused problems because of "mixed data" in column stationList 
mydf.to_hdf('tmp_with_cat.hdf5', 'journeys', mode='w', format='t', complevel=9, complib='bzip2') 

mydf.pop('stationList') 

# this again works fine 
mydf.to_hdf('tmp_with_cat_without_stationList.hdf5', 'journeys', mode='w', format='t', complevel=9, complib='bzip2') 

edit2: Между тем я пробовал разные вещи, чтобы избавиться от этой проблемы. Один из них состоял в том, чтобы преобразовать записи столбца columnList в тупели (возможно, поскольку они не должны быть изменены) и также преобразовать его в категорию. Но это ничего не изменило. Вот строки, которые я добавил после цикла преобразования (только для полноты):

mydf.stationList = [tuple(x) for x in mydf.stationList.values] 
mydf.stationList.astype('category') 
+0

Возникает вопрос? Также это поможет, если вы разместили фактический код для создания тестового фреймворка. – Goyo

+0

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

+0

Похоже, вы не можете хранить как категоричные, так и списки/кортежи в том же формате hdf5 (это может быть исправлено в будущем). Я не могу сказать вам, что менять, не зная больше о ваших требованиях. Возможно, оставим строки в виде строк, возможно, выберите другое представление для элементов stationList ... есть слишком много опций. – Goyo

ответ

5

У вас есть две проблемы:

  1. Вы хотите сохранить категорические данные в файле HDF5;
  2. Вы пытаетесь сохранить произвольные объекты (т. Е. stationList) в файле HDF5.

Как вы обнаружили, категориальные данные (в настоящее время?) Поддерживаются только в формате «таблицы» для HDF5.

Однако хранение произвольных объектов (список строк и т. Д.) На самом деле не является тем, что поддерживается форматом HDF5. Pandas работает над этим для вас, сериализуя эти объекты с помощью pickle, а затем сохраняя рассол в виде строки произвольной длины (что, я думаю, не поддерживается всеми форматами HDF5). Но это будет медленным и неэффективным и никогда не будет поддерживаться HDF5.

На мой взгляд, у вас есть два варианта:

  1. Сводные данные, так что вы один ряд данных по имени станции. Затем вы можете хранить все файлы в формате HDF5 в формате таблицы. (Это хорошая практика в целом, см. Hadley Wickham on Tidy Data.)
  2. Если вы действительно хотите сохранить этот формат, то вы можете сохранить весь фрейм данных, используя to_pickle(). Это не будет иметь проблемы с каким-либо объектом (например,список строк и т. д.) вы бросаете на него.

Лично я бы рекомендовал вариант 1. Вы можете использовать быстрый, двоичный формат файла. А стержень также облегчит другие операции с вашими данными.

+1

Эта проблема очень стандартная, но решений мало – Tensor

Смежные вопросы