Как использовать шкалы размеров HDF5 в h5py

В HDF5 используется концепция шкал измерения, как описано в HDF5 и h5py. Однако в объяснениях используются как краткие, так и общие примеры, поэтому я не совсем понимаю, как использовать масштабы измерений. А именно, учитывая набор данных f['coordinates'] в некотором файле HDF5 f = h5py.File('data.h5'):

>>> f['coordinates'].value
array([[ 52.60636111,   4.38963889],
   [ 52.57877778,   4.43422222],
   [ 52.58319444,   4.42811111],
   ..., 
   [ 52.62269444,   4.43130556],
   [ 52.62711111,   4.42519444],
   [ 52.63152778,   4.41905556]])

Я хотел бы пояснить, что первый столбец — это широта, а второй — долгота. Используются ли для этого размерные шкалы? Или они используются для обозначения того, что единицей измерения являются градусы. Или оба?

Возможно, другой конкретный пример лучше иллюстрирует использование масштабов измерений? Если он у вас есть, поделитесь им, даже если вы не используете h5py.


person equaeghe    schedule 17.01.2017    source источник
comment
Я думаю, вы хотите использовать dims labels. По ссылке h5py, f['data'].dims[0].label = 'z'   -  person hpaulj    schedule 18.01.2017
comment
@hpaulj Спасибо, что подумали вместе. Чтобы понять, какими должны быть метки в конкретном контексте (то есть не с каким-то общим 'z'), мне нужно сначала понять, для чего используются шкалы измерений, в идеале на конкретном примере.   -  person equaeghe    schedule 18.01.2017
comment
Это просто для вашего сведения. hdf5 не использует его, если только это не задокументировано.   -  person hpaulj    schedule 18.01.2017


Ответы (1)


В частности, для этого вопроса лучшим ответом, вероятно, будет использование атрибутов:

f['coordinates'].attrs['columns'] = ['latitude', 'longitude']

Но размерные шкалы полезны и для других целей. Я покажу, для чего они нужны, как их можно использовать так же, как и атрибуты, и как на самом деле вы можете использовать свой f['coordinates'] набор данных в качестве масштаба для какого-либо другого набора данных.

Размерные шкалы

Я согласен с тем, что эти страницы документации не так ясны, как могли бы быть, потому что они запускают сложные возможности и увязают в технических деталях, прежде чем на самом деле объясняют основные концепции. Я думаю, что несколько простых примеров должны прояснить ситуацию.

Во-первых, предположим, что вы отслеживали температуру снаружи в течение дня — возможно, измеряя ее каждый час в течение часа, всего 24 измерения. Вы можете представить это как два столбца данных: один для часа, а другой для температуры. Вы можете сохранить это как единый набор данных формы 24x2. Но время и температура имеют разные единицы измерения и действительно разные типы данных. Таким образом, может иметь смысл хранить время и температуру в виде отдельных наборов данных — возможно, с именами "time" и "temperature", каждый из которых имеет форму 24. Но вам также нужно немного более четко понимать, что это такое и как они связаны с каждым из них. разное. Именно для таких отношений и нужны шкалы измерений.

Если вы представляете график зависимости температуры от времени, вы можете обозначить горизонтальную ось как Время (час дня), а шкала для горизонтальной оси будет сами часы, сообщая вам горизонтальное положение, в котором можно отобразить каждую температуру. Вы можете сохранить эту информацию через h5py следующим образом:

with h5py.File("temperatures.h5", "w") as f:
    time = f.create_dataset("time", data=...)
    time.make_scale("hour of day")
    temp = f.create_dataset("temperature", data=...)
    temp.dims[0].label = "Time"
    temp.dims[0].attach_scale(time)

Обратите внимание, что аргумент make_scale представляет собой конкретную информацию об этом конкретном наборе данных time — в данном случае единицы измерения, которые мы использовали для измерения time, — тогда как label — это более общая концепция этого измерения. Также обратите внимание, что на самом деле более стандартно прикреплять информацию о единицах измерения в качестве атрибутов, но мне больше нравится этот подход для указания единиц шкалы из-за его простоты.

Теперь предположим, что мы измерили температуру в трех разных местах — скажем, в Лос-Анджелесе, Чикаго и Нью-Йорке. Теперь наш массив температур будет иметь форму 24x3. Нам по-прежнему нужна шкала времени для dim[0], но теперь у нас есть еще и dim[1].

with h5py.File("temperatures.h5", "w") as f:
    time = f.create_dataset("time", data=...)
    time.make_scale("hour of day")
    cities = f.create_dataset("cities",
        data=[s.encode() for s in ["Los Angeles", "Chicago", "New York"]]
    )
    cities.make_scale("city")
    temp = f.create_dataset("temperature", data=...)
    temp.dims[0].label = "Time"
    temp.dims[0].attach_scale(time)
    temp.dims[1].label = "Location"
    temp.dims[1].attach_scale(cities)

Возможно, было бы полезнее хранить широту и долготу вместо названий городов. На самом деле вы можете прикрепить оба типа масштаба к одному и тому же измерению. Просто добавьте такой код внизу последнего блока кода:

    latlong = f.create_dataset("latlong",
        data=[[34.0522, 118.2437], [41.8781, 87.6298], [40.7128, 74.0060]]
    )
    latlong.make_scale("latitude and longitude (degrees)")
    temp.dims[1].attach_scale(latlong)

Наконец, вы можете получить доступ к этим меткам и шкалам следующим образом:

with h5py.File("temperatures.h5", "r") as f:
    print('Datasets:', list(f))
    print('Temperature dimension labels:', [dim.label for dim in f['temperature'].dims])
    print('Temperature dim[1] scales:', f['temperature'].dims[1].keys())
    latlong = f['temperature'].dims[1]['latitude and longitude (degrees)'][:]
    print(latlong)

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

Datasets: ['cities', 'latlong', 'temperature', 'time']
Temperature dimension labels: ['Time', 'Location']
Temperature dim[1] scales: ['city', 'latitude and longitude (degrees)']
[[ 34.0522 118.2437]
 [ 41.8781  87.6298]
 [ 40.7128  74.006 ]]
person Mike    schedule 08.07.2020