爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 14087|回复: 7

[求助] 关于python读取二进制文件

[复制链接]

新浪微博达人勋

发表于 2019-4-29 16:19:41 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
小弟最近在学习python玩耍一下,下载了风云4A 的经纬度信息,想读取了之后玩耍一下。
先给出经纬度的信息:
文件格式
文件从北向南按行(从西到东)填写,每个网格对应 16 字节,前8 字节为经度值,后 8 字节为纬度值,double 类型,高字节在前

小弟下载的是4km的数据,行列式2748*2748

用python的程序是:
import numpy as np
f = open("E:\data\FullMask_Grid_4000.gz",'rb')
data = np.zeros((2748,2748*2))
for i in range(2748):
    for j in range(2748*2):
        zuobiao = f.read(8)
        elem = struct.unpack("d", zuobiao)
        ele = np.array(elem,dtype = 'double')
        data[i,j] =  ele

错误提示:
error: unpack requires a buffer of 8 bytes

请教各位大神,是哪里的问题。
如果有更好的程序也求分享,
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2019-5-5 09:55:19 | 显示全部楼层
import numpy as np
import gzip
num = 2748
data = np.zeros((num,num*2))
Lon = np.zeros((num,num))
Lat = np.zeros((num,num))
with gzip.open('E:\data\FullMask_Grid_4000.raw.gz', 'rb') as f:
    for i in range(num):
        for j in range(num*2):
            zuobiao = f.read(8)
            elem = struct.unpack("d", zuobiao)
            elem = np.float64(elem)
            data[i,j] =  elem
            if (j % 2 == 0):  #偶数
                p = int(j/2)
                Lat[i,p] = elem
            else:
                p = int((j-1)/2)
                Lon[i,p] = elem


目前这个是我使用的,将经纬度值分离了开来。
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2019-4-30 09:02:50 | 显示全部楼层
gz是压缩文件,需要先解压再读。
import gzip
with gzip.open('E:\data\FullMask_Grid_4000.gz', 'rb') as f:
    data = np.zeros((2748,2748*2))
    for i in range(2748):
        for j in range(2748*2):
            zuobiao = f.read(8)
            elem = struct.unpack("f", zuobiao)
            ele = np.array(elem,dtype = 'float')
            data[i,j] =  ele
手头没环境,你先试试看
密码修改失败请联系微信:mofangbao
回复 支持 1 反对 0

使用道具 举报

新浪微博达人勋

发表于 2019-4-29 17:01:55 | 显示全部楼层
不知道理解对不对,仅供参考:
文件总字节数为2748*2748*16,你的j循环一次就读了2748*2*8个字节,i循环第2轮就把总字节数读完了,i循环第3轮就没字节可读了,所以出现unpack requires a buffer of 8 bytes
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

发表于 2019-4-29 17:24:02 | 显示全部楼层
python中没有double,改成float
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-4-30 08:50:30 | 显示全部楼层
835479131 发表于 2019-4-29 17:01
不知道理解对不对,仅供参考:
文件总字节数为2748*2748*16,你的j循环一次就读了2748*2*8个字节,i循环第 ...

你好,我认为并不是这样呢
第一次i循环读取了2748*2*8的字节 就是2748*16的字节 所以需要循环2748次才能完成所有的读取呀 就是2748*2748*16个字节
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-4-30 08:52:54 | 显示全部楼层
1099221723 发表于 2019-4-29 17:24
python中没有double,改成float

请问该如何改呢?我改成这样
f = open("E:\data\FullMask_Grid_4000.gz",'rb')
data = np.zeros((2748,2748*2))
for i in range(2748):
    for j in range(2748*2):
        zuobiao = f.read(8)
        elem = struct.unpack("f", zuobiao)
        ele = np.array(elem,dtype = 'float')
        data[i,j] =  ele


之后错误提示是   error: unpack requires a buffer of 4 bytes
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

新浪微博达人勋

 楼主| 发表于 2019-4-30 09:51:06 | 显示全部楼层
zasd9999 发表于 2019-4-30 09:02
gz是压缩文件,需要先解压再读。
import gzip
with gzip.open('E:\data\FullMask_Grid_4000.gz', 'rb') a ...

num = 2748
with gzip.open('E:\data\FullMask_Grid_4000.raw.gz', 'rb') as f:
    data = np.zeros((num,num*2))
    for i in range(num):
        for j in range(num*2):
            zuobiao = f.read(8)
            elem = struct.unpack("d", zuobiao)
            elem = np.float64(elem)
            data[i,j] =  elem

非常感谢您的帮助,这样可以完成读取。后面我完善好程序之后再发上来供大家参考。
目前关于其中f和d的区别我还没有弄清楚,f 和d 都可以读取。让我还是比较困惑的,我查询了下python中4字节的好像是f  8字节的好像是double  但是目前实验下来都可以使用,就比较奇怪了
密码修改失败请联系微信:mofangbao
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表