python读取二进制文件(简单小白版)以PIOMAS的海温数据读取为例

总代码

import numpy as np
import struct

def get_data_level1(datafile, n1=360, n2=120, levels=10):
    data = np.zeros(n1 * n2 * levels * 12)
    i = 0
    #"rb"二进制读取
    fh = open(datafile, "rb")
    bys = fh.read(4)
    while bys:
        #每读一个数,存为一个元组a=(3.14,)
        bys_unpk = struct.unpack("f", bys)
        data[i] = bys_unpk[0]
        i += 1
        bys = fh.read(4)

    fh.close()
    data = data.reshape(12, levels, n1 * n2)
    data_level1 = data[:, 0, :]

    return data_level1

def get_grid_lonlat(gridfile, n1=360, n2=120):
    lonlat_arr = np.zeros(n1 * n2 * 2)
    i = 0
    fh = open(gridfile)
    for line in fh:
        linestrs = line.split()
        for s in linestrs:
            lonlat_arr[i] = float(s)
            i += 1

    fh.close()
    lon_arr = lonlat_arr[:n1 * n2]
    lon_arr[lon_arr > 180] = lon_arr[lon_arr > 180] - 360
    lat_arr = lonlat_arr[n1 * n2:]

    return lon_arr, lat_arr


if __name__ == "__main__":
    gridfile = "/g/aaa/sst_dir/grid.dat"
    datafile = "/g/aaa/sst_dir/otemp1_10.H2002"

    lon_arr, lat_arr = get_grid_lonlat(gridfile)
    otemp1 = get_data_level1(datafile)

    #输出经纬度和温度数据
    print(lon_arr, lat_arr)
    print(otemp1)

代码解释:

我读取的二进制数据有两个,一个是PIOMAS的温度数据(otemp1_10.H2002),一个是温度数据对应的经纬度数据(grid.dat)。

一、PIOMAS的温度数据(otemp1_10.H2002)

二进制文件是按一定的顺序直接存储在一个个字节中的,所以整个文件就是一堆0和1,需要我们把它们解码出来,那怎么解码呢,就要去网站上找到该数据的数据类型,根据不同数据类型来进行解码。

根据网页的信息可以看到,存储在otemp1_10.H2002里面的是单精度浮点数,也就是4个字节为一个温度数据,所以首先我们要把文件以4个字节为单位进行顺序读取。

(另外,由于otemp1_10.H2002的格网点是360*120,有10个不同深度,12个月,所以我先创建了360 * 120 * 10 * 12的矩阵,大家可根据自己的数据维度和大小修改)

读取完放入事先创建好的矩阵中,根据二进制文件数据的存放顺序来reshape矩阵。(这个也需要在网站上找,比如我的二进制危机是按照月-深度-网格顺序存的,所以我也按照这个顺序reshape矩阵)

def get_data_level1(datafile, n1=360, n2=120, levels=10):
    data = np.zeros(n1 * n2 * levels * 12)
    i = 0
    #"rb"二进制读取
    fh = open(datafile, "rb")
    bys = fh.read(4)
    while bys:
        #每读4个字节即为一个温度数据,存为一个元组 eg:a=(3.14,)
        bys_unpk = struct.unpack("f", bys)
        data[i] = bys_unpk[0]
        i += 1
        bys = fh.read(4)

    fh.close()
    data = data.reshape(12, levels, n1 * n2)
    data_level1 = data[:, 0, :]

    return data_level1

二、经纬度数据(grid.dat)

这个就不是二进制文件了,该文件存储顺序是:先存了所有经度,然后存所有纬度,用记事本打开看到:

直接对每一行split读取就好啦

def get_grid_lonlat(gridfile, n1=360, n2=120):
    lonlat_arr = np.zeros(n1 * n2 * 2)
    i = 0
    fh = open(gridfile)
    for line in fh:
        linestrs = line.split()
        for s in linestrs:
            lonlat_arr[i] = float(s)
            i += 1

    fh.close()
    lon_arr = lonlat_arr[:n1 * n2]
    #将0-360经度转为-180-180
    lon_arr[lon_arr > 180] = lon_arr[lon_arr > 180] - 360
    lat_arr = lonlat_arr[n1 * n2:]

    return lon_arr, lat_arr

猜你喜欢

转载自blog.csdn.net/Mluoo/article/details/129176333