ValueError: сохранение сохранения в режиме добавления в Pytables - PullRequest
1 голос
/ 10 июля 2020

У меня есть 100 изображений, каждое из 85*85 size (width*height), заданных numpy массивом (data) следующим образом.

import numpy as np
import tables as tb


data = np.random.rand(100, 85, 85)
print (data.shape)

Я хочу сохранить каждое изображение в h5 один за другим в режиме добавления.

fo = "data.h5"

h5 = tb.open_file(fo, mode='w')

group = h5.create_group(h5.root, 'data')

atom = tb.Float64Atom()

ds = h5.create_earray(group, 'test', atom,
                       (0, data.shape[1], data.shape[2]))

for ix in range(data.shape[0]):
    dd = data[ix, :, :]
       
    ds.append(dd)

ds.flush()
ds.close()

Однако я получил следующую ошибку:

ValueError: ранги добавленного объекта (2) и /data/test EArray ( 3) различаются

1 Ответ

2 голосов
/ 10 июля 2020

Будьте осторожны с синтаксисом при доступе к элементам массива data. Когда вы используете dd = data[ix, :, :], dd.shape=(85, 85) Вам нужно dd = data[ix:ix+1, :, :], чтобы получить 1 строку.

Построчная загрузка данных неэффективна, если вам нужно добавить много строк. Лучше поместить их в массив и добавить весь массив. Это показано в создании ds2.append(data)

Вот обновленное решение. Обратите внимание, я предпочитаю with/as открывать файлы для более чистой обработки ошибок файлов.

with tb.open_file(fo, mode='w') as h5:
    group = h5.create_group(h5.root, 'data')
    atom = tb.Float64Atom() 
    ds = h5.create_earray(group, 'test', atom,
                         (0, data.shape[1], data.shape[2]))
    for ix in range(data.shape[0]):
        dd = data[ix:ix+1, :, :]
        print (dd.shape)   
        ds.append(dd)

# Method to create Earray with parent groups, 
# then append all image data at one time
    ds2 = h5.create_earray('/data2', 'test2', atom,
                     (0, data.shape[1], data.shape[2]),
                     createparents=True)
    ds2.append(data)

Если вы хотите загрузить все данные в 1 Earray, это просто загрузить, используя ссылку на параметр obj=data ваш массив. При этом определение формы сохраняется в размере 0. См. Измененный код ниже.

h5 = tb.open_file(fo, mode='w')
group = h5.create_group(h5.root, 'data')
ds = h5.create_earray('/data', 'test', atom,
                     (0, data.shape[1], data.shape[2]),
                     obj=data)
ds.flush() # not necessary
ds.close() # not necessary
h5.close() ## REQUIRED!!!!
...