#python #hdf5 #h5py
Вопрос:
Мне нужна помощь.
У меня есть файл HDF5, содержащий данные о спектре (время, частоты и уровень мощности заданной частоты в данный момент времени). Вот как структурирован файл (с использованием HDFView):
HDF-представление файла данных
Основными группами (ключами) являются ЧАСЫ, а затем внутри находятся минуты, причем каждая минута является своей собственной группой (ключом). Данные были собраны за 0,02 секунды в течение 60 секунд… таким образом, существует 3000 строк…и диапазоны частот 256 (т. Е. Начинаются с 1 МГц и заканчиваются на 26 МГц, на расстоянии 256 друг от друга. Например.e. 23 —gt; 23:10 —gt;gt; 2D массив мощности
0 0 1 2 ..... 255 1 -53.672386 -53.82235 -53.773468 ..... -50.566887 2 -53.85694 -53.945183 -53.63385 ..... -51.306465 3 -53.709038 -53.55101 -53.55305 ..... -52.7324906 . . . 2999 -53.23989 -51.501495 -50.681602 -52.227474
Я могу получить доступ к данным отдельных минут и собрать их в массивы, а затем построить данные. Подобный этому:
import h5py import numpy as np import matplotlib.pyplot as plt # Read in the HDF5 file file = h5py.File("/home/tom/Desktop/2021-10-28_ch0.hdf5", 'r') # Search for the main groups in the file. The main groups are hours: 20, 22, etc... # Select one of the hours (i.e. 23) hour = file['23'] # Search for the subgroups (keys) within the chosen hour. There are "hour:minutes" i.e. 23:10 #for key in hour.keys(): #print( key ) # Select key with data for minutes 10, 11, 12, 13 and save into individual arrays: minute_data_10=hour['23:10'][()] minute_data_11=hour['23:11'][()] minute_data_12=hour['23:12'][()] minute_data_13=hour['23:13'][()] # Generate a 1D array of TIME spanning 4 minutes (because we ingested # 4x 1 minute slices of data: time = np.linspace(0, 60*4, 3000*4) # Generate a 1D array of FREQUENCY frequency = np.linspace(1.575E0, 26.82402336E0, 256) # Combine minute_data_10 minute_data_11 minute_data_12 and minute_data_13 along the time axis (axis=0) comb_min = np.concatenate( (minute_data_10, minute_data_11, minute_data_12, minute_data_13), axis=0 ) print( comb_min.shape ) # Plot the data im = plt.pcolormesh(frequency, time, comb_min, cmap='jet') plt.colorbar(im).ax.tick_params(labelsize=10) plt.title('Spectrum') plt.ylabel('Seconds ago...') #plt.xlabel('frequency in Hz') im.axes.xaxis.set_ticklabels([]) plt.show()
Я вручную определяю каждую минуту (мин. 10, 11, 12, 13), объединяя их, а затем нанося на график.
но…что я хотел бы сделать, так это автоматически проглотить ВСЕ минуты за ВСЕ часы по моему выбору, а затем объединить их в один сюжет. Например, как я могу проглотить ВСЕ минуты за 15 часов, а затем построить график спектра ? ИЛИ, как я мог бы построить график первых 5 часов данных ?
Комментарии:
1. просто зацикливайтесь на всех ключах в час или зацикливайтесь на всех часах и ключах в течение тех часов, которые вы выберете
2. Да, попробовал это, и это хорошо работает (хотя все еще изучает Python). Спасибо!
Ответ №1:
Файлы HDF5 являются самоописывающимися. (Другими словами, вы можете получить имена групп или наборов данных из файла-вам не нужно знать их заранее.) Как отмечалось выше, вы делаете это с .keys()
помощью метода. (Примечание: объекты h5py НЕ являются словарями; h5py просто использует синтаксис словаря Python для доступа к именам.)
Использование ключей/имен имеет дополнительное преимущество, заключающееся в том, что вы читаете только существующие наборы данных. Глядя на ваше изображение, можно увидеть наборы данных для времени 15:00
и 15:02
, но не для 15:01
. (Этот пробел имеет дополнительные последствия при создании вашего сюжета — но это другая проблема.)
Приведенный ниже код показывает, как это сделать. Он использует тот же подход: создайте список объектов h5py, затем объедините их в один массив с np.concatenate
помощью . Он также собирает hh:mm
время (из имен наборов данных) в списке, который вы можете использовать для создания time
массива.
Я использовал файловый контекстный менеджер Python. Это предпочтительнее методов открытия/закрытия (позволяет избежать оставления файлов открытыми и улучшает читаемость).
Простой пример (жестко закодированный для [’15’] часовой группы):
with h5py.File('/home/tom/Desktop/2021-10-28_ch0.hdf5.h5','r') as h5f: times = [] collect = [] hh = '15' for hhmm in h5f[hh].keys(): times.append(hhmm) collect.append(h5f[hh][hhmm]) comb_min = np.concatenate( collect, axis=0 ) print(times) print(len(collect), comb_min.shape)
Более общий пример (считывает все группы[часы] и наборы данных[‘чч:мм’]):
with h5py.File('/home/tom/Desktop/2021-10-28_ch0.hdf5.h5','r') as h5f: times = [] collect = [] for hh in h5f.keys(): for hhmm in h5f[hh].keys(): times.append(hhmm) collect.append(h5f[hh][hhmm]) comb_min = np.concatenate( collect, axis=0 ) print(times) print( len(collect), comb_min.shape )
Ответ №2:
Это просто обобщение того, что у вас уже есть. Чтобы получить все 15 часов:
hh = '15' hour = file[hh] collect = [hour[f'{hh}:{mm:02d}'] for mm in range(60)] comb_min = np.concatenate( collect, axis=0 ) print( comb_min.shape )
Чтобы получить первые 5 часов:
collect = [hours[f'{hh:02d}:{mm:02d}'] for hh in range(5) for mm in range(60)] comb_min = np.concatenate( collect, axis=0 ) print( comb_min.shape )
И похоже for
, что пункты написаны наоборот, но это не так.
Комментарии:
1. Может потребоваться проверка наличия каждого
hh:mm
набора данных. Например, на изображении показано15:00
и15:02
, но нет15:01
.2. Я не вижу этого в постановке задачи, но мой код получит такую проверку в том смысле, что он вызовет найденное исключение, если запись не существует.