Хранение наборов строковых данных в hdf5 с Юникодом

Я пытаюсь сохранить переменные строковые выражения из файла, который содержит специальные символы, такие как ø, æ , and å, Вот мой код:

import h5py as h5
file = h5.File('deleteme.hdf5','a')
dt = h5.special_dtype(vlen=str)
dset = file.create_dataset("text",(1,),dtype=dt)
dset.attrs[str(1)] = "some text with ø, æ, å"

Однако текст не хранится должным образом. Сохраненные данные содержат текст:

"some text with \37777777703\37777777670, \37777777703\37777777646,\37777777703\37777777645"

Как правильно хранить специальные символы? Я пытался следовать руководству, приведенному в документации здесь: Строки в HDF5 - UTF-8 переменной длины

Редактировать:

Выход был от h5dump. Ответ ниже подтвердил, что символы правильно хранятся как utf-8.

2 ответа

Решение

С:

import numpy as np
import h5py as h5
file = h5.File('deleteme.hdf5','w')
dt = h5.special_dtype(vlen=str)
dset = file.create_dataset("text",(3,),dtype=dt)
dset[:] = 'ø æ å'.split()
dset.attrs["1"] = "some text with ø, æ, å"
file.close()

file = h5.File('deleteme.hdf5','r')
print(file['text'][:])
print(file['text'].attrs["1"])
file.close()

Я вижу:

$ python3 stack44661467.py 
['ø' 'æ' 'å']
some text with ø, æ, å

То есть h5py действительно видит / интерпретирует строки как юникод - запись и чтение.

С помощью утилиты дампа:

$ h5dump deleteme.hdf5 
HDF5 "deleteme.hdf5" {
GROUP "/" {
   DATASET "text" {
      DATATYPE  H5T_STRING {
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_UTF8;
         CTYPE H5T_C_S1;
      }
      DATASPACE  SIMPLE { ( 3 ) / ( 3 ) }
      DATA {
      (0): "\37777777703\37777777670", "\37777777703\37777777646",
      (2): "\37777777703\37777777645"
      }
      ATTRIBUTE "1" {
         DATATYPE  H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_UTF8;
            CTYPE H5T_C_S1;
         }
         DATASPACE  SCALAR
         DATA {
         (0): "some text with \37777777703\37777777670, \37777777703\37777777646, \37777777703\37777777645"
         }
      }
   }
}
}

Обратите внимание, что в обоих случаях datatype отмечен UTF8

     DATATYPE  H5T_STRING {
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_UTF8;
         CTYPE H5T_C_S1;
      }

Вот что говорят доктора:

http://docs.h5py.org/en/latest/strings.html

Они могут хранить любой символ, который может хранить строка Unicode в Python, за исключением NULL. В файле они создаются как строки переменной длины с набором символов H5T_CSET_UTF8.

Позволять h5py (или другой читатель) беспокоиться о переводе \37777777703\37777777670 как правильный символ Юникода.

Вы должны попытаться сохранить ваши данные в формате UTF-8, выполнив следующие действия:

Для кодирования в формате utf-8 (перед сохранением с h5py) выполните:

u"æ".encode("utf-8")

который возвращает:

'\xc3\xa6'

Затем для декодирования вы можете использовать строку decode следующим образом:

'\xc3\xa6'.decode("utf-8")

который бы вернулся:

æ

Надеюсь, поможет!

РЕДАКТИРОВАТЬ

Когда вы открываете файлы и хотите, чтобы они были в UTF-8, вы можете использовать параметр кодирования в методе чтения файла:

f = open(fname, encoding="utf-8")

Это должно помочь правильно кодировать исходный файл.

Источник: python-notes

Другие вопросы по тегам