[!NOTE] Tips
H5文件是层次数据格式第5代的版本(Hierarchical Data Format,HDF5),它是用于存储科学数据的一种文件格式和库文件。由美国超级计算中心与应用中心研发的文件格式,用以存储和组织大规模数据。
其本身类似于我们的树形文件存储系统
可以看到,通过group
容器来组织和管理数据,而数据存放在Dataset
里面。
打开其结构可以看到,本数据的标准有三个属性:
- Attribute
- Data
- Global
Global和Attribute都是一些元数据记录,重点关注Data部分,里面有一些处理好的结果。
其数据组织以表结构进行,如果读取,其结果为:
这是一个 144x72
的图像。
现在将通过Python进行读取。
导入必要的模块:
python
import os
import h5py
import pandas as pd
import cv2 as cv
这些模块在安装好Anaconda
后,直接使用pip
命令安装下面这两个:
pip install h5py
pip install opencv-python
来到我们的文件路径,需要对文件树进行遍历,用的是os.walk
方法,该方法会返回(上级路径,当前路径下的文件夹,当前路径下的文件)这样一个三元组,其将当前路径下的文件视作叶子节点,所以我们只需要判断当前路径下的文件是否为空,如果不为空,就获取这个文件就行了。
python
h5Path=[]
dir_path = r"C:\Users\Administrator\Downloads\20-23"
for dirpath, dirnames, filenames in os.walk(dir_path):
# 当前路径,路径下的文件夹,文件名
if filenames!=[]:
h5Path+=[os.path.join(dirpath,i) for i in filenames]
尝试读取一个文件看看
python
for i in h5Path:
hdf = h5py.File(i, "r")
print(hdf.keys())
break
# output
# <KeysViewHDF5 ['Attribute', 'Data', 'Global']>
成功了,然后通过visit
方法可以遍历元素,这个用于快速了解hdf5
文件的group
结构
python
hdf.visit(lambda x:print(x))
那么,我们现在以数据XCO2Average
为例,进行读取和保存:
python
# 获取其中的元素,例如XCO2Average
img=hdf['Data']['latticeInformation']['XCO2Average'][:]
这个结果应该是一个ndarray
结构的数据,我们直接用opencv
进行读取和保存:
python
cv.imshow("img",img)
cv.waitKey(0)
cv.imwrite(r"C:\Users\Administrator\Desktop\新建文件夹\XCO2Average.jpg",img)
可以看到,Data
一共有三层结构,我们现在尝试自动化进行读取。
python
def getItems(k="Data"):
res=[]
keys=hdf.visit(lambda x:res.append(x.split("/")) if x.startswith(k) and len(x.split("/"))==3 else None)
return res
这个函数可以直接获取所有的三层结构。
那么,我们想要获取某个数据,就可以这样啦:
python
keys=getItems()
for k in keys:
try:
img=hdf[k[0]][k[1]][k[2]][:]
path_=os.path.join(p,k[2])
cv.imwrite(path_+".jpg",img)
pd.DataFrame(img).to_csv(path_+".csv")
except:
pass
[!warning]
为什么这里用
Try
?因为有部分数据读取失败了,但这部分是缺失该属性导致的,不影响其他属性和数据
python
for i in h5Path:
try:
hdf=h5py.File(i,"r")
_savePathDict=(i.split("20-23")[1])[1:-4]
if not os.path.exists(p:=os.path.join(savePath,_savePathDict)):
os.makedirs(p)
print(p)
for k in keys:
try:
img=hdf[k[0]][k[1]][k[2]][:]
path_=os.path.join(p,k[2])
cv.imwrite(path_+".jpg",img)
pd.DataFrame(img).to_csv(path_+".csv")
except:
pass
except:
pass
- [l] 值得一提的是,os.makedirs会自动处理
\
,也就是自动创建下级目录,所以这里保持原先的路径位置就好,只不过现在是用文件名创建了一个文件夹,并将读取出来的结果保存在里面。
结果如图所示:
完整代码:
依赖环境:
pip install h5py
pip install opencv-python
python
import os
import h5py
import pandas as pd
import cv2 as cv
h5Path=[]
# 这里修正路径
dir_path = r"C:\Users\Administrator\Downloads\20-23"
for dirpath, dirnames, filenames in os.walk(dir_path):
# 当前路径,路径下的文件夹,文件名
if filenames!=[]:
h5Path+=[os.path.join(dirpath,i) for i in filenames]
savePath=r"D:\20-23_toImg"
def getItems(k="Data"):
res=[]
hdf.visit(lambda x:res.append(x.split("/")) if x.startswith(k) and len(x.split("/"))==3 else None)
return res
keys=getItems()
for i in h5Path:
try:
hdf=h5py.File(i,"r")
_savePathDict=(i.split("20-23")[1])[1:-4]
if not os.path.exists(p:=os.path.join(savePath,_savePathDict)):
os.makedirs(p)
print(p)
for k in keys:
try:
img=hdf[k[0]][k[1]][k[2]][:]
path_=os.path.join(p,k[2])
cv.imwrite(path_+".jpg",img)
pd.DataFrame(img).to_csv(path_+".csv")
except:
pass
except:
pass