首页 > 编程语言 >【Python实例】hdf文件简介及基于Python导入hdf文件

【Python实例】hdf文件简介及基于Python导入hdf文件

时间:2024-11-01 10:47:01浏览次数:5  
标签:文件 HDF Python 数据 dataset hdf data

【Python实例】hdf文件简介及基于Python导入hdf文件

HDF(Hierarchical Data Format)是一种用于存储和组织大量数据的文件格式。HDF 文件可用于多种应用,特别是在科学和工程领域。

.hdf文件概述

一个HDF5文件是一种存放两类对象的容器:dataset和group。 Dataset是类似于数组的数据集,而group是类似文件夹一样的容器,存放dataset和其他group。
在使用h5py的时候需要牢记一句话:groups类比词典,dataset类比Numpy中的数组。
在这里插入图片描述

  • HDF4 文件通常以 .hdf 或 .h4 结尾,而 HDF5 文件通常以 .h5 或 .hdf5 结尾。
    需要专门的软件(如HDF View)才能打开预览文件的内容。HDF5 文件结构中有 2 primary objects: Groups 和 Datasets。

  • 每个 dataset 可以分成两部分: 原始数据 (raw) data values 和 元数据 metadata (a set of data that describes and gives information about other data => raw data)。
    对于每一个dataset 而言,除了数据本身之外,这个数据集还会有很多的属性 attribute。在hdf5中,还同时支持存储数据集对应的属性信息,所有的属性信息的集合就叫做metadata.

hdf工具-HDFView

HDFView的下载及安装可参见另一博客-【hdf文件工具】HDFView安装及使用教程

基于Python导入hdf文件

常用工具和库

  • h5py:Python 中用于读取和写入 HDF5 文件的库。
  • PyTables:另一个 Python 库,专注于高性能的 HDF5 文件操作。

实例1:判断是否为hdf文件

具体Python代码如下:

import os

def is_hdf5(file_path):
    """检查文件是否为 HDF5 格式"""
    with open(file_path, 'rb') as f:
        signature = f.read(8)
    return signature == b'\x89HDF\r\n\x1a\n'

def is_hdf4(file_path):
    """检查文件是否为 HDF4 格式"""
    with open(file_path, 'rb') as f:
        # HDF4 文件的开头通常包含特定的标志
        signature = f.read(4)
    return signature.startswith(b'HDF')

def is_hdf(file_path):
    """检查文件是否为 HDF 文件(HDF4 或 HDF5)"""
    return is_hdf4(file_path) or is_hdf5(file_path)

hdf_file_path = 'D:/path/to/your/file.hdf'  # 确保路径正确

if not os.path.exists(hdf_file_path):
    print("文件不存在,请检查路径。")
else:
    try:
        if is_hdf(hdf_file_path):
            if is_hdf5(hdf_file_path):
                import h5py
                with h5py.File(hdf_file_path, 'r') as hdf:
                    print("打开 HDF5 文件成功!")
                    print("Keys in the HDF file:", list(hdf.keys()))
            elif is_hdf4(hdf_file_path):
                from pyhdf import HDF
                hdf = HDF(hdf_file_path, HDF.READ)
                print("打开 HDF4 文件成功!")
                print("可用数据集:", hdf.datasets())
        else:
            print("文件格式未知,不支持该文件类型。")
    
    except Exception as e:
        print("发生错误:", e)

实例2:打开并读取hdf4文件(地面反照率数据)

以下载的2020年地面反照率数据为例,数据详细介绍可参见另一博客-【数据集】Global Land Surface Satellites (GLASS):LAI、Albedo、LST、FVC

Python代码如下:

import h5py
from pyhdf.SD import SD, SDC

# 打开 HDF 文件
hdf_file_path = 'D:/0 DataBase/8 GLASS02B03.V50_Albedo/GLASS02B03.V50.A2020001.2021300.hdf'  # 替换为你的文件路径

try:
    # 直接打开 HDF 文件
    data = SD(hdf_file_path, SDC.READ)
    print("成功打开 HDF 文件!")

    # 打印文件中的所有数据集
    datasets = data.datasets()
    print("文件中的数据集:")

    for dataset_name in datasets.keys():
        # 获取数据集信息
        dataset_info = datasets[dataset_name]
        data_type = dataset_info[0]  # 数据类型
        data_shape = dataset_info[1]  # 数据形状

        print(f"数据集名称: {dataset_name}, 数据类型: {data_type}, 数据形状: {data_shape}")

        # 读取数据集
        dataset = data.select(dataset_name)
        data_values = dataset[:]

        # 打印数据集的部分内容(前10个值)
        print(f"数据集 '{dataset_name}' 的前10个值: {data_values.flatten()[:10]}")

    # 关闭 HDF 文件
    data.end()

except OSError as e:
    print("打开 HDF 文件失败:", e)
except Exception as e:
    print("发生错误:", e)

输出结果如下:(数据空间分辨率:0.05°;空间范围:全球)

成功打开 HDF 文件!
文件中的数据集:
数据集名称: BSA_VIS, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'BSA_VIS' 的前10个值: [9360 9360 9360 9360 9360 9360 9360 9360 9360 9360]
数据集名称: BSA_NIR, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'BSA_NIR' 的前10个值: [5560 5560 5560 5560 5560 5560 5560 5560 5560 5560]
数据集名称: BSA_shortwave, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'BSA_shortwave' 的前10个值: [7960 7960 7960 7960 7960 7960 7960 7960 7960 7960]
数据集名称: WSA_VIS, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'WSA_VIS' 的前10个值: [9160 9160 9160 9160 9160 9160 9160 9160 9160 9160]
数据集名称: WSA_NIR, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'WSA_NIR' 的前10个值: [5360 5360 5360 5360 5360 5360 5360 5360 5360 5360]
数据集名称: WSA_shortwave, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'WSA_shortwave' 的前10个值: [7760 7760 7760 7760 7760 7760 7760 7760 7760 7760]
数据集名称: QC, 数据类型: ('YDim:GLASS02B03', 'XDim:GLASS02B03'), 数据形状: (3600, 7200)
数据集 'QC' 的前10个值: [32747 32747 32747 32747 32747 32747 32747 32747 32747 32747]

实例3:绘制图形(地面反照率数据)

绘制图形如下:
在这里插入图片描述

相关代码如下:

import h5py
from pyhdf.SD import SD, SDC
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap

# 设置字体为 Times New Roman
plt.rcParams['font.family'] = 'Times New Roman'

# 打开 HDF 文件
hdf_file_path = 'D:/0 DataBase/8 GLASS02B03.V50_Albedo/GLASS02B03.V50.A2020001.2021300.hdf'  # 替换为你的文件路径

try:
    # 直接打开 HDF 文件
    data = SD(hdf_file_path, SDC.READ)
    print("成功打开 HDF 文件!")

    # 打印文件中的所有数据集
    datasets = data.datasets()
    print("文件中的数据集:")

    for dataset_name in datasets.keys():
        # 获取数据集信息
        dataset_info = datasets[dataset_name]
        data_type = dataset_info[0]  # 数据类型
        data_shape = dataset_info[1]  # 数据形状

        print(f"数据集名称: {dataset_name}, 数据类型: {data_type}, 数据形状: {data_shape}")

        # 提取数据集 'BSA_VIS'
        dataset_name = 'BSA_VIS'
        dataset = data.select(dataset_name)
        data_values = dataset[:].astype(np.float32)

        # 生成经纬度网格
        latitudes = np.linspace(-90, 90, data_values.shape[0])  # 3600 行
        longitudes = np.linspace(-180, 180, data_values.shape[1])  # 7200 列

        # 找出最大值和最小值
        bsa_max = np.nanmax(data_values[data_values != -1])  # 使用 nanmax 处理无效数据
        bsa_min = np.nanmin(data_values[data_values != -1])

        # 打印最大值和最小值
        print(f"BSA_VIS 最小值: {bsa_min}, 最大值: {bsa_max}")

        # 绘制数据集图形
        plt.figure(figsize=(10, 6))

        # 创建 Basemap 实例
        m = Basemap(projection='cyl', llcrnrlat=-90, urcrnrlat=90,
                    llcrnrlon=-180, urcrnrlon=180, resolution='c')

        # 将 -1 设置为缺测值
        data_values[data_values == -1] = np.nan  # 用 NaN 替换 -1

        # 绘制陆地边界
        m.drawcoastlines()
        m.drawcountries()
        m.drawmapboundary(fill_color='lightblue')

        # 绘制经纬度网格和刻度标签
        m.drawparallels(np.arange(-90., 91., 30.), labels=[1, 0, 0, 0], fontsize=10)  # 纬度
        m.drawmeridians(np.arange(-180., 181., 60.), labels=[0, 0, 0, 1], fontsize=10)  # 经度

        # 反转纬度数组
        #latitudes = latitudes[::-1]  # 反转纬度顺序

        # 将数据投影到 Basemap 中
        x = longitudes
        y = latitudes
        data_values = np.ma.masked_invalid(data_values)  # 避免无效数据

        # 使用 contourf 绘制数据
        lon_mesh, lat_mesh = np.meshgrid(x, y)
        cmap = plt.get_cmap('viridis')
        cmap.set_bad(color='white')  # 将缺测值设为白色

        cs = m.contourf(lon_mesh, lat_mesh, data_values[::-1, :], cmap=cmap,
                        vmin=bsa_min, vmax=bsa_max)  # 设置颜色范围

        # 添加颜色条
        cbar = plt.colorbar(cs, orientation='vertical', pad=0.02)
        cbar.set_label('BSA_VIS')  # 设置颜色条标签
        cbar.ax.tick_params(labelsize=10)  # 设置颜色条刻度标签大小

        # 设置经纬度刻度标签
        m.drawmeridians(np.arange(-180, 181, 30), labels=[1, 0, 0, 0])  # 经度
        m.drawparallels(np.arange(-90, 91, 30), labels=[0, 0, 0, 1])  # 纬度

        plt.xlabel('Longitude (°)', fontsize=14, labelpad=15)
        plt.ylabel('Latitude (°)', fontsize=14, labelpad=30)
        plt.title('Surface Albedo in 2020', fontsize=16)

        # 设置坐标轴刻度值字体大小
        plt.tick_params(axis='both', labelsize=14)

        plt.show()

        # 关闭 HDF 文件
        data.end()


    # 关闭 HDF 文件
    data.end()

except OSError as e:
    print("打开 HDF 文件失败:", e)
except Exception as e:
    print("发生错误:", e)

参考

标签:文件,HDF,Python,数据,dataset,hdf,data
From: https://blog.csdn.net/qq_44246618/article/details/143396916

相关文章

  • Liunx xfs文件系统的f_type
    xfs_info是一个用于显示XFS文件系统信息的工具。在xfs_info命令中,ftype参数用于指定文件类型的处理方式。XFS文件系统支持两种文件类型处理方式:ftype=0:传统方式(Legacymode)ftype=1:扩展方式(Extendedmode)ftype=0(传统方式)在这种模式下,XFS文件系统使用传统的Unix文件......
  • python使用魔法函数__getitem__实现字典和列表式访问自定义类型
    起因想起C++可以实现运算符重载,以实现以数组的方式([])访问我们的类.我想要实现一个类,可以同时用类似于字典和就想到python能不能实现这个效果,而且显然是可以的,不然numpy是怎么实现属于自己的数组的?#期望实现效果classmyclass: passc=myclass()#像这样使用[]访......
  • 使用axios下载二进制流文件
    1.下载文件的api接口,在api.js中书写exportconstdownloadFiles=(params)=>{returnaxios.post(`${baseUrl}/downloadFiles`,params,{responseType:"blob",});};2.调用api接口,在需要使用下载的方法中书写,使用async和await异步加载的方式letres=awaitdow......
  • Python中的文件I/O操作
    在Python编程中,文件I/O(输入/输出)是一个重要的主题,涉及如何读取和写入文件。无论是处理文本文件还是二进制文件,Python提供了简洁易用的接口。本文将介绍如何在Python中进行文件I/O操作,包括读取、写入和文件处理的最佳实践。文件打开与关闭在Python中,使用内置的open()函数打开......
  • 使用Python和Selenium获取BOOS直聘职位信息
    文章目录引言环境准备网页分析代码解析1.导入必要的库2.定义爬虫类3.启动浏览器4.主要爬取逻辑5.提取职位信息6.保存数据到CSV7.初始化CSV文件8.清理和整理CSV数据9.全部代码结语引言在当今就业比较困难,很多人对于要投递的岗位相关行业信息不了解,如果有招......
  • Java读取properties配置文件
    需要导入的jar<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.14</version></dependency>方法:使用Spring PropertiesLoaderUtils.loadProperties();方法一......
  • Python中类的三个方法
    在Python中,类有三种常用的方法,以及相应的装饰器。下面是它们的详细介绍:1.类的方法实例方法(InstanceMethod)实例方法是类中定义的常规方法,第一个参数通常是self,指代实例本身。实例方法可以访问和修改实例的属性。pythonclassMyClass:definstance_method(sel......
  • Python 常用的 50 个提效小脚本
    Python常用的50个提效小脚本原创 huaan9527 测试开发学习交流 2024年09月28日11:22 浙江文件和目录管理批量重命名文件   importosforfilenameinos.listdir('.'):os.rename(filename,filename.replace('old','new'))查找大文件  ......
  • C#读取Json配置文件
    1、安装NuGet包:Newtonsoft.Json2、新建Confgi.json{"K-Fins":-1,"K-Zs":0.2,}3、在Models文件中新建AppConfig.cs和ConfigManager.cspublicclassAppConfig{publicdoubleKFins{get;set;}publicdoublekZs{get;s......
  • 程序文件、网页、数据库三者字符集编码不一致导致出现乱码问题
    问题原因程序文件、网页、数据库三者字符集编码不一致导致出现乱码问题。解决方案将程序文件、网页、数据库三者的字符集编码设为一致。推荐使用UTF-8编码,因为UTF-8可以支持全世界几乎所有国家的语言。具体步骤1.程序文件的字符集编码检查和设置文件编码:使用文本编辑器(......