You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Blosc压缩的HDF5文件读取时遇OSError问题求助

Blosc2压缩HDF5文件读取报错:OSError: Can't synchronously read data (can't open directory)

我用Python代码生成了采用Blosc2压缩的HDF5文件,生成过程无报错,但读取trainval组下的image_log数据集时触发上述错误。其他压缩方式可正常读取,已尝试重装h5py与hdf5plugin、执行磁盘检查、多次重新运行脚本,问题仍未解决,存储文件的D盘尚有300GB可用空间。


生成文件代码

# Create forecast training data file
import h5py
import hdf5plugin
#mmap_array = np.memmap('video_prediction_224.dat', dtype='uint8', mode='w+', shape=(n_images, 224, 224, 3))
sampling_interval = 2
n_valid = 307518 # index 307517 is the last valid index
n_trainval = 149680

n_test = 6145
chunk_shape = (1, stack_height+1, *output_img_shape)

batch_size = 8000
#for sampling_interval in sampling_interval_all:
resume_idx = 0
with h5py.File('video_prediction_224_testing.h5', 'w') as f:

    #image_log = f.create_dataset('image_log', shape = (n_images, 224, 224, 3), dtype ='uint8', )

    if resume_idx and 'image_log' in f:
        # Resume mode - datasets already exist
        image_log_ds = f['image_log']
        pv_log_ds = f['pv_log'] 
        pv_pred_ds = f['pv_pred']
        print(f"Resuming from existing datasets. Current size: {image_log_ds.shape[0]}")
    else:
        # First run - create new datasets

        trainval_group = f.create_group('trainval')
        test_group = f.create_group('test')
        image_log_trainval_ds = trainval_group.create_dataset(
            'image_log',
            shape=(n_trainval, stack_height+1, *output_img_shape),
            chunks=chunk_shape,
            compression=hdf5plugin.Blosc2(cname='zstd', clevel=1, filters=hdf5plugin.Blosc2.SHUFFLE),
            dtype='uint8'
        )
        pv_log_trainval_ds = trainval_group.create_dataset(
            'pv_log',
            shape=(n_trainval, stack_height+1),
            dtype='float64'
        )
        pv_pred_trainval_ds = trainval_group.create_dataset(
            'pv_pred',
            shape=(n_trainval,),
            dtype='float64'
        )
        image_log_test_ds = test_group.create_dataset(
            'image_log',
            shape=(n_test, stack_height+1, *output_img_shape),
            chunks=chunk_shape,
            compression=hdf5plugin.Blosc2(cname='zstd', clevel=1, filters=hdf5plugin.Blosc2.SHUFFLE),
            dtype='uint8'
        )
        pv_log_test_ds = test_group.create_dataset(
            'pv_log',
            shape=(n_test, stack_height+1),
            dtype='float64'
        )
        pv_pred_test_ds = test_group.create_dataset(
            'pv_pred',
            shape=(n_test,),
            dtype='float64'
        )
        print("Creating new datasets")

    
    #image_log = np.empty([0,stack_height+1]+output_img_shape,dtype = 'uint8')
    #pv_log = np.empty([0, stack_height+1])
    #pv_pred = np.empty([0])

    last_valid_index = 0
    curr_trainval_size = 0
    curr_test_size = 0

    tic = time.process_time()
    for b in range(resume_idx if (resume_idx and 'image_log' in f) else 0, 8000, batch_size):
        current_batch_size =  min(batch_size, n_images-b)
        # Initialize variables to save pv values
        #image_log_batch = np.zeros([n_images,stack_height+1]+output_img_shape,dtype = 'uint8')
        idx_test_batch = get_subarray_between_values(np.asarray(idx_test),b,b+current_batch_size)

        image_log_batch = np.zeros([current_batch_size,stack_height+1]+output_img_shape,dtype = 'uint8')
        
        #all_times_batch = all_times[b*batch_size : b*batch_size + current_batch_size]
        pv_log_batch = np.zeros((current_batch_size,stack_height+1))
        pv_pred_batch = np.zeros(current_batch_size)
        validity_mask = np.ones(current_batch_size,dtype = bool)
        
        

        sampling_interval_td = datetime.timedelta(minutes = sampling_interval) - datetime.timedelta(seconds=1)
        for i in range(current_batch_size):
            count = b+i

            
            # See if the specified sampling frequency is met 
            if all_times[count] - all_times[last_valid_index] > sampling_interval_td:

                # Collecting groud truth for predicted value
                pred_time = all_times[count]+datetime.timedelta(minutes=forecast_horizon)
                
                pv_pred_idx = find_time_within_nparray(pv_data.index,pred_time)
                if pv_pred_idx is None:# if prediction ground truth not found
                    validity_mask[i] = False
                    #print(all_times[i],'has no PV pred')
                else: 
                    pv_pred_batch[i] = pv_data.iloc[pv_pred_idx] 

                # Collecting image log and PV log
                for j in range(stack_height+1):
                    log_time = all_times[count] - datetime.timedelta(minutes = j)
                    # Collecting a stack of image
                    log_time_idx = find_time_within_nparray(all_times,log_time)
                    if log_time_idx is not None:
                        image_log_batch[i,j] = all_images[log_time_idx]
                    else:
                        validity_mask[i] = False
                        #print(all_times[count],'has no image log')
                        break

                    # Collecting a stack of PV value
                    pv_log_idx = find_time_within_nparray(pv_data.index,log_time)
                    # Check if PV value present
                    if pv_log_idx is None:
                        validity_mask[i] = False
                        #print(all_times[count],'has no PV log')
                        break
                    else: 
                        pv_log_batch[i,j] = pv_data.iloc[pv_log_idx]    

            else: # if this is in between the sampling points, discard
                validity_mask[i] = False
            
            if validity_mask[i]:
                last_valid_index = count
            
        # Prompt progress of current work

        print('processed {0}/{1} images'.format(b+current_batch_size,len(all_times)))
            
        
        # Only pick out the valid time points
        #all_times_batch = all_times_batch[validity_mask]
        test_mask = np.zeros(current_batch_size, dtype=bool)
        test_mask[idx_test_batch-b] = True
        validity_test_mask = validity_mask & test_mask
        trainval_mask = np.ones(current_batch_size, dtype=bool)
        trainval_mask[idx_test_batch-b] = False
        validity_trainval_mask = validity_mask & trainval_mask

        image_log_trainval_batch = image_log_batch[validity_trainval_mask]
        pv_log_trainval_batch = pv_log_batch[validity_trainval_mask]
        pv_pred_trainval_batch = pv_pred_batch[validity_trainval_mask]

        image_log_test_batch = image_log_batch[validity_test_mask]
        pv_log_test_batch = pv_log_batch[validity_test_mask]
        pv_pred_test_batch = pv_pred_batch[validity_test_mask]
        # Store information
        
        print("storing data")
        #image_log_ds[curr_size:curr_size+validity_mask.sum()] = image_log_batch
        #pv_log_ds[curr_size:curr_size+validity_mask.sum()] = pv_log_batch
        #pv_pred_ds[curr_size:curr_size+validity_mask.sum()] = pv_pred_batch
        image_log_trainval_ds[curr_trainval_size:curr_trainval_size+validity_trainval_mask.sum()] = image_log_trainval_batch
        #print("image_log_trainval_batch: ",image_log_trainval_batch)
        #print("image_log_trainval_ds.shape: ",image_log_trainval_ds.shape)
        print("stored trainval image log")
        pv_log_trainval_ds[curr_trainval_size:curr_trainval_size+validity_trainval_mask.sum()] = pv_log_trainval_batch
        print("stored trainval pv log")
        pv_pred_trainval_ds[curr_trainval_size:curr_trainval_size+validity_trainval_mask.sum()] = pv_pred_trainval_batch
        print("stored trainval pv pred")
        image_log_test_ds[curr_test_size:curr_test_size+validity_test_mask.sum()] = image_log_test_batch
        print("stored test image log")
        pv_log_test_ds[curr_test_size:curr_test_size+validity_test_mask.sum()] = pv_log_test_batch
        pv_pred_test_ds[curr_test_size:curr_test_size+validity_test_mask.sum()] = pv_pred_test_batch

        curr_trainval_size += validity_trainval_mask.sum()
        print("trainval_size: ",validity_trainval_mask.sum())
        curr_test_size += validity_test_mask.sum()
        print("test_size: ",validity_test_mask.sum())

        print('For sampling frequency: ',sampling_interval,' minutes')
        #print('Expected finishing time:', datetime.datetime.now()+
        #       datetime.timedelta(seconds = (time.process_time() - tic)*(len(all_times)/(b+batch_size))))
        f.flush()
        del image_log_trainval_batch
        del pv_log_trainval_batch
        del pv_pred_trainval_batch
        del image_log_test_batch
        del pv_log_test_batch
        del pv_pred_test_batch

    pred_folder_child = os.path.join(pred_folder,'frequency_'+str(sampling_interval))
    #store_trainval_test(all_times,image_log,pv_log,pv_pred,pred_folder_child)

读取代码

# generate handler for the hdf5 data
forecast_dataset = h5py.File(data_path, 'r')

# show structure of the hdf5 data
def get_all(name):
    if name!=None:
        print(forecast_dataset[name])

forecast_dataset.visit(get_all)

img = forecast_dataset["trainval"]["image_log"][0]
print(img)

报错信息

data_folder: d:\PVOutputPrediction\data
data_path: d:\PVOutputPrediction\video_prediction_224_second.h5
output_folder: d:\PVOutputPrediction\model_output\UNet_sky_image_PV_mapping
<HDF5 group "/test" (3 members)>
<HDF5 dataset "image_log": shape (6145, 16, 224, 224, 3), type "|u1">
<HDF5 dataset "pv_log": shape (6145, 16), type "<f8">
<HDF5 dataset "pv_pred": shape (6145,), type "<f8">
<HDF5 group "/trainval" (3 members)>
<HDF5 dataset "image_log": shape (149680, 16, 224, 224, 3), type "|u1">
<HDF5 dataset "pv_log": shape (149680, 16), type "<f8">
<HDF5 dataset "pv_pred": shape (149680,), type "<f8">
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
Cell In[7], line 3
      1 import matplotlib.pyplot as plt
----> 3 img = forecast_dataset["trainval"]["image_log"][0]
      4 print(img)

File h5py/_objects.pyx:56, in h5py._objects.with_phil.wrapper()

File h5py/_objects.pyx:57, in h5py._objects.with_phil.wrapper()

File d:\PVOutputPrediction\pytorch_env\Lib\site-packages\h5py\_hl\dataset.py:820, in Dataset.__getitem__(self, args, new_dtype)
    818 if self._fast_read_ok and (new_dtype is None):
    819     try:
--> 820         return self._fast_reader.read(args)
    821     except TypeError:
    822         pass  # Fall back to Python read pathway below

File h5py/_selector.pyx:376, in h5py._selector.Reader.read()

OSError: Can't synchronously read data (can't open directory)

解决方案

  1. 调整Blosc2压缩参数
    尝试更换压缩算法或关闭SHUFFLE过滤器,避免潜在的索引兼容问题:

    # 更换为lz4压缩算法
    compression=hdf5plugin.Blosc2(cname='lz4', clevel=1)
    # 或关闭SHUFFLE过滤器
    compression=hdf5plugin.Blosc2(cname='zstd', clevel=1, filters=[])
    
  2. 修改分块大小
    当前单条数据作为一个分块的设置可能导致读取时的目录索引错误,尝试使用更合理的分块尺寸,比如:

    chunk_shape = (32, 16, 224, 224, 3)  # 根据stack_height调整第二个维度
    
  3. 规避h5py快速读取
    报错来自h5py的快速读取模块,可通过强制使用Python读取路径绕过:

    # 用切片再取索引的方式触发Python读取路径
    img = forecast_dataset["trainval"]["image_log"][0:1][0]
    # 或直接转换为numpy数组
    img = np.array(forecast_dataset["trainval"]["image_log"])[0]
    
  4. 更新依赖库版本
    旧版本hdf5plugin可能存在Blosc2兼容性问题,执行升级:

    pip install --upgrade hdf5plugin h5py
    
  5. 校验文件完整性
    使用h5py内置的校验功能检查文件是否损坏:

    import h5py
    with h5py.File(data_path, 'r') as f:
        f.verify()
    

    若校验失败,说明文件生成过程存在隐性中断,需重新生成并确保写入过程无异常。


内容的提问来源于stack exchange,提问作者Aiden Yun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 14:15:53