Необъяснимое поведение при использовании vlen с h5py

Я использую h5py для создания набора данных. Поскольку я хочу хранить массивы с разным размером #of rows, я использую vlen h5py special_type. Однако я испытываю поведение, которое не могу объяснить, может быть, вы поможете мне понять, что происходит:

>>>> import h5py
>>>> import numpy as np
>>>> fp = h5py.File(datasource_fname, mode='w') 
>>>> dt = h5py.special_dtype(vlen=np.dtype('float32'))
>>>> train_targets = fp.create_dataset('target_sequence', shape=(9549, 5,), dtype=dt)
>>>> test
Out[130]: 
array([[ 0.,  1.,  1.,  1.,  0.,  1.,  1.,  0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  1.]])
>>>> train_targets[0] = test
>>>> train_targets[0]
Out[138]: 
array([ array([ 0.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.], dtype=float32),
        array([ 1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.,  0.], dtype=float32),
        array([ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.,  0.,  0.], dtype=float32),
        array([ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.], dtype=float32),
        array([ 0.,  1.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.], dtype=float32)], dtype=object)

Я ожидаю, что train_targets[0] будет такой формы, однако я не могу распознать строки в своем массиве. Они кажутся полностью перемешанными, однако это последовательно. Под этим я подразумеваю, что каждый раз, когда я пробую приведенный выше код, train_targets[0] выглядит одинаково.

Чтобы уточнить: первый элемент в моем train_targets, в данном случае test, имеет форму (5,11), однако второй элемент может иметь форму (5,38), поэтому я использую vlen.

спасибо за помощь

Мат


person Mathew    schedule 30.05.2015    source источник


Ответы (1)


Я думаю

train_targets[0] = test

сохранил ваш массив (11,5) как упорядоченный массив F в строке train_targets. Судя по фигуре (9549,5), это ряд из 5 элементов. И поскольку это vlen, каждый элемент представляет собой массив из 1d длины 11.

Вот что вы получите в train_targets[0] — массив из 5 массивов, каждая форма (11,), со значениями, взятыми из test (порядок F).

Итак, я думаю, что есть 2 вопроса: что означает 2d shape и что позволяет vlen.


Моя версия h5py предшествует версии 2.3, поэтому я получаю только строку vlen. Но я подозреваю, что ваша проблема может заключаться в том, что vlen работает только с массивами 1d, так сказать, расширением байтовых строк.

Имеет ли 5 в shape=(9549, 5,) какое-то отношение к 5 в test.shape? Я так не думаю, по крайней мере так, как это видят numpy и h5py.

Когда я создаю файл, следующий примеру строки vlen:

>>> f = h5py.File('foo.hdf5')
>>> dt = h5py.special_dtype(vlen=str)
>>> ds = f.create_dataset('VLDS', (100,100), dtype=dt)

а затем выполните:

ds[0]='this one string'

и посмотрите на ds[0], я получаю массив объектов со 100 элементами, каждый из которых является этой строкой. То есть я поставил целый ряд ds.

ds[0,0]='another'

это правильный способ установить только один элемент.

vlen — это «переменная длина», а не «переменная форма». В то время как https://www.hdfgroup.org/HDF5/doc/TechNotes/VLTypes.html документация не совсем ясна по этому поводу, я думаю, вы можете хранить массивы 1d с формой (11,) и (38,) с vlen, но не 2d.


На самом деле вывод train_targets воспроизводится с помощью:

In [54]: test1=np.empty((5,),dtype=object)
In [55]: for i in range(5):
    test1[i]=test.T.flatten()[i:i+11]

Это 11 значений, взятых из транспонирования (порядок F), но сдвинутых для каждого подмассива.

person hpaulj    schedule 30.05.2015
comment
Спасибо за объяснение @hpaulj. Решение заключается в том, что нужно явно задавать каждый вектор, а не всю матрицу. 2д действительно не работает. - person Mathew; 09.06.2015