Хранение наборов строковых данных в 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