2017-01-04 3 views
0

Я хотел бы организовать свои собранные данные (из компьютерных симуляций) в файл hdf5 с помощью Python. Я измерял положения и скорости [x, y, z, vx, vy, vz] всех атомов в определенной пространственной области на протяжении многих временных шагов. Количество атомов, конечно, меняется от временного шага к временному шагу.H5PY - Как хранить много 2D-массивов разных размеров

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

[ 
[ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2] ], 
[ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2], [x3,y3,z3,vx3,vy3,vz3] ] 
] 

(2 временные шаги, первый шаг по времени: 2 атома, второй шаг по времени: 3 атома)

Моя идея состояла в том, чтобы создать hdf5 в Python, который хранит всю информацию. На каждом временном шаге он должен хранить 2d массив Alls позиций/скоростей всех атомов, т.е.

dataset[0] = [ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2] ] 
dataset[1] = [ [x1,y1,z1,vx1,vy1,vz1], [x2,y2,z2,vx2,vy2,vz2], [x3,y3,z3,vx3,vy3,vz3] ]. 

Идея понятна, я думаю. Однако я борюсь с определением правильного типа данных набора данных с переменной длиной массива.

Мой код выглядит следующим образом:

import numpy as np 
import h5py 

file = h5py.File ('file.h5','w') 

columnNo = 6  
rowtype = np.dtype("%sfloat32" % columnNo) 
dt = h5py.special_dtype(vlen=np.dtype(rowtype)) 

dataset = file.create_dataset("dset", (2,), dtype=dt) 

print dataset.value 

testarray = np.array([[1.,2.,3.,2.,3.,4.],[1.,2.,3.,2.,3.,4.]]) 
print testarray 

dataset[0] = testarray 
print dataset[0] 

Это, однако, не работает. Когда я запускаю скрипт, я получаю сообщение об ошибке «Объект AttributeError:« float »не имеет атрибута« dtype ».» Кажется, что мой определенный dtype ошибочен.

Кто-нибудь видит, как он должен быть определен правильно?

Большое спасибо, Sven

ответ

0

Ошибка в вашем случае похоронен, хотя понятно, что происходит при попытке присвоить testarray к dataset:

Traceback (most recent call last): 
    File "stack41465480.py", line 26, in <module> 
    dataset[0] = testarray 
    File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper (/build/h5py-GhwtGD/h5py-2.6.0/h5py/_objects.c:2577) 
... 
    File "h5py/_conv.pyx", line 712, in h5py._conv.ndarray2vlen (/build/h5py-GhwtGD/h5py-2.6.0/h5py/_conv.c:6171) 
AttributeError: 'float' object has no attribute 'dtype' 

Я не квалифицированный с special_dtype и vlen, но я смог написать структурированные массивы numpy до h5py.

import numpy as np 
import h5py 

file = h5py.File ('file.h5','w') 

columnNo = 6  
# rowtype = np.dtype("%sfloat32" % columnNo) 
rowtype = np.dtype([('f0', '<f4',(6,))]) 
dt = h5py.special_dtype(vlen=np.dtype(rowtype)) 

print('rowtype',rowtype) 
print('dt',dt) 
dataset = file.create_dataset("dset", (2,), dtype=rowtype) 

print('value') 
print(dataset.value[0]) 

arr = np.ones((2,),dtype=rowtype) 
print(repr(arr)) 
dataset[0] = arr[0] 
print(dataset.value) 

testarray = np.array([([1.,2.,3.,2.,3.,4.],),([2.,3.,4.,1.,2.,3.],)], dtype=rowtype) 
print(repr(testarray)) 

dataset[1] = testarray[1] 
print(dataset.value) 
print(dataset.value['f0']) 

производства

1316:~/mypy$ python3 stack41465480.py 
rowtype [('f0', '<f4', (6,))] 
dt object 
value 
([0.0, 0.0, 0.0, 0.0, 0.0, 0.0],) 
array([([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],), ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)], 
     dtype=[('f0', '<f4', (6,))]) 
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([0.0, 0.0, 0.0, 0.0, 0.0, 0.0],)] 
array([([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],), ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)], 
     dtype=[('f0', '<f4', (6,))]) 
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)] 
[[ 1. 1. 1. 1. 1. 1.] 
[ 2. 3. 4. 1. 2. 3.]] 
0

Спасибо за быстрый ответ. Это очень помогло.

Если я теперь просто изменить тип данных набора данных для

dtype = dt, 

я получаю то, что я хотел бы иметь.

Здесь код Python (для полноты):

import numpy as np 
import h5py 

file = h5py.File ('file.h5','w') 

columnNo = 6 

rowtype = np.dtype([('f0', '<f4',(6,))]) 
dt = h5py.special_dtype(vlen=np.dtype(rowtype)) 

print('rowtype',rowtype) 
print('dt',dt) 
dataset = file.create_dataset("dset", (2,), dtype=dt) 

# print('value') 
# print(dataset.value[0]) 

arr = np.ones((3,),dtype=rowtype) 
# print(repr(arr)) 
dataset[0] = arr 
# print(dataset.value) 

testarray = np.array([([1.,2.,3.,2.,3.,4.],),([2.,3.,4.,1.,2.,3.],)], dtype=rowtype) 
# print(repr(testarray)) 

dataset[1] = testarray 
print(dataset.value) 
for i in range(2): print dataset[i] 

И соответствующему выходу читает

('rowtype', dtype([('f0', '<f4', (6,))])) 
('dt', dtype('O')) 
[ array([([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],), 
     ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],), ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)], 
     dtype=[('f0', '<f4', (6,))]) 
array([([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],), ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)], 
     dtype=[('f0', '<f4', (6,))])] 
[([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) ([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],) 
([1.0, 1.0, 1.0, 1.0, 1.0, 1.0],)] 
[([1.0, 2.0, 3.0, 2.0, 3.0, 4.0],) ([2.0, 3.0, 4.0, 1.0, 2.0, 3.0],)] 

Просто чтобы получить это право: проблема в моем исходном коде было плохое определение моя структура данных rowtype, правильно?

Лучшие, Sven

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