使用np.fromfile()

时间:2016-05-20 22:37:19

标签: python numpy multidimensional-array structured-array

我有一个包含多个部分的二进制文件。每个部分都有自己的模式(即整数,浮点数和字符串的位置)。

每个部分的模式都是已知的。但是,在该部分中出现模式的次数是未知的。每条记录介于两个相同的整数之间。这些整数表示记录的大小。节名称介于两个整数记录长度变量之间:8和8.同样在每个节中,有多个记录(已知)。

Header
---------------------
Known header pattern
---------------------
8 Section One 8
---------------------
Section One pattern repeating i times
---------------------
8 Section Two 8
---------------------
Section Two pattern repeating j times
---------------------
8 Section Three 8
---------------------
Section Three pattern repeating k times
---------------------

这是我的方法:

  
    
        
  1. 使用f.read(record_length)循环访问并读取每条记录,如果记录为8字节,则转换为字符串,这将是节名称。

  2.     
  3. 然后我致电:np.fromfile(file,dtype=section_pattern,count=n)

  4.        

我为每个部分打电话np.fromfile

我遇到的问题有两个:

  
    
        
  1. 如何在不进行第一遍读取的情况下确定每个部分的n?
  2.     
  3. 读取每条记录以查找部分名称似乎效率很低。有没有更有效的方法来实现这一目标?
  4.        

节名始终在两个整数记录变量之间:8和8。

这是一个示例代码,请注意,在这种情况下,我不必指定计数,因为OES部分是最后一部分:

with open('m13.op2', "rb") as f:

    filesize = os.fstat(f.fileno()).st_size
    f.seek(108,1) # skip header

    while True:

        rec_len_1 = unpack_int(f.read(4))
        record_bytes = f.read(rec_len_1)
        rec_len_2 = unpack_int(f.read(4))
        record_num = record_num + 1

        if rec_len_1==8:

            tablename = unpack_string(record_bytes).strip()

            if tablename == 'OES':

                OES = [

                # Top keys
                ('1','i4',1),('op2key7','i4',1),('2','i4',1),
                ('3','i4',1),('op2key8','i4',1),('4','i4',1),
                ('5','i4',1),('op2key9','i4',1),('6','i4',1),

                # Record 2 -- IDENT
                ('7','i4',1),('IDENT','i4',1),('8','i4',1),
                ('9','i4',1),
                ('acode','i4',1),
                ('tcode','i4',1),
                ('element_type','i4',1),
                ('subcase','i4',1),

                ('LSDVMN','i4',1), # Load set number
                ('UNDEF(2)','i4',2), # Undefined
                ('LOADSET','i4',1), # Load set number or zero or random code identification number
                ('FCODE','i4',1), # Format code
                ('NUMWDE(C)','i4',1), # Number of words per entry in DATA record
                ('SCODE(C)','i4',1), # Stress/strain code
                ('UNDEF(11)','i4',11), # Undefined
                ('THERMAL(C)','i4',1), # =1 for heat transfer and 0 otherwise
                ('UNDEF(27)','i4',27), # Undefined
                ('TITLE(32)','S1',32*4), # Title
                ('SUBTITL(32)','S1',32*4), # Subtitle
                ('LABEL(32)','S1',32*4), # Label
                ('10','i4',1),

                # Record 3 -- Data
                ('11','i4',1),('KEY1','i4',1),('12','i4',1),
                ('13','i4',1),('KEY2','i4',1),('14','i4',1),
                ('15','i4',1),('KEY3','i4',1),('16','i4',1),
                ('17','i4',1),('KEY4','i4',1),('18','i4',1),
                ('19','i4',1),
                ('EKEY','i4',1), #Element key = 10*EID+Device Code. EID = (Element key)//10
                ('FD1','f4',1),
                ('EX1','f4',1),
                ('EY1','f4',1),
                ('EXY1','f4',1),
                ('EA1','f4',1),
                ('EMJRP1','f4',1),
                ('EMNRP1','f4',1),
                ('EMAX1','f4',1),
                ('FD2','f4',1),
                ('EX2','f4',1),
                ('EY2','f4',1),
                ('EXY2','f4',1),
                ('EA2','f4',1),
                ('EMJRP2','f4',1),
                ('EMNRP2','f4',1),
                ('EMAX2','f4',1),
                ('20','i4',1)]

                nparr = np.fromfile(f,dtype=OES)


            if f.tell() == filesize:
                break

0 个答案:

没有答案