读取格式化行以填充数组

时间:2019-06-05 17:02:50

标签: python numpy

我正在尝试使用python将txt文件中的某些行读入数组。 txt文件由FORTRAN格式化,格式为3个整数,两个为3个字符长度,一个为2个字符长度(即24238 8.,其中值为24,238,8)。每行有7 3个整数“组”。下面是txt文件的8行。

24238 8. 27237 8. 38 82 6. 38 96 6. 39 76 6. 39 77 6. 39 78 6.BARR  1
39 79 6. 39 80 6. 39 81 6. 39 82 6. 39 84 6. 39 85 6. 39 86 6.BARR  2
39 88 8. 39 89 8. 39 9010. 39 91 7. 39 92 7. 39 93 5. 39 96 6.BARR  3
39 9710. 39 9810. 39 9910. 3910010. 3910113. 3910212. 3910312.BARR  4
3910412. 3910512. 40 72 6. 40 73 6. 40 74 6. 40 75 6. 40 76 6.BARR  5
40 80 9. 40 8110. 40 8212. 40 8312. 40 84 8. 4010512. 4010612.BARR  6
40107 9. 40108 9. 40109 9. 41 70 6. 41 71 6. 41 77 6. 41 78 6.BARR  7
41 79 8. 41 80 8. 4110910. 41110 6. 41111 6. 41184 8. 42 73 2.BARR  8

我也不希望担心每一行末尾的BARR 1等问题,可以忽略它。我创建了一个初始值数组,希望将其用txt文件中的值填充。

import numpy as np
basin = open("il3_barrier","r")
zbm = np.full((171,251),-300)

我想要的是“三个”组中的第三个值,以基于第一个和第二个值填充数组。例如,我希望值8占据位置24、238等处的数组。

我正在使用来自stackoverflow上另一个答案的一段代码。但是我不确定如何使用它来遍历线路。

def slices(s, *args):
    position = 0
    for length in args:
        yield s[position:position + length]
        position += length

在此示例中,仅查看8行,我将尝试如下所示:

for h in range(0,8): 
    tempLine = basin.readline()
    for k in range(0,7):
        inw,jnw,hw = list(slices(tempLine,3,3,2))
        inw = int(inw)
        jnw = int(jnw)
        zbm [inw,jnw] = hw

这仅返回每行的第一组值,并且不会遍历整行。有没有办法让它在一行中遍历每组数字?也许有另一种方法可以做到?

3 个答案:

答案 0 :(得分:0)

您在这里= ^ .. ^ =

代码中的简短说明。

import numpy as np

# load raw data
raw_data = []
with open('raw_data.txt', 'r') as file:
    data = file.readlines()
    for item in data:
        raw_data.append(item.strip())

# collect coordinates data
coordinates_data = []
for item in raw_data:
    for i in range(0, 63, 9):
        coordinates_data.append((item[0+i:2+i].strip(), item[2+i:5+i].strip(), item[6+i:7+i].strip().replace('.', '')))

# get values for array size
max_x = 0
max_y = 0
for item in coordinates_data:
    if max_x < int(item[0]):
        max_x = int(item[0])
    if max_y < int(item[1]):
        max_y = int(item[1])

# create empty array
final_array = np.zeros((max_x+1, max_y+1))

# load data into array
for item in coordinates_data:
    final_array[int(item[0]), int(item[1])] = int(item[2])

答案 1 :(得分:0)

使用delimiter的域宽度版本,我可以使用genfromtxt加载前两组数字(txt是文件示例的多行粘贴):

In [221]: dels = [2,3,3, 3,3,3]; cols=[0,1,2,3,4,5]                                                    
In [222]: np.genfromtxt(txt.splitlines(), delimiter=dels, usecols=cols, dtype=float)                   
Out[222]: 
array([[ 24., 238.,   8.,  27., 237.,   8.],
       [ 39.,  79.,   6.,  39.,  80.,   6.],
       [ 39.,  88.,   8.,  39.,  89.,   8.],
       [ 39.,  97.,  10.,  39.,  98.,  10.],
       [ 39., 104.,  12.,  39., 105.,  12.],
       [ 40.,  80.,   9.,  40.,  81.,  10.],
       [ 40., 107.,   9.,  40., 108.,   9.],
       [ 41.,  79.,   8.,  41.,  80.,   8.]])

由于'8',我不得不使用dtype float。领域。我想我可以缩短字段并跳过“。”代替。

或者,如果我指定了None类型,它将构成一个结构化数组,其中包含整数和浮点dtype字段的混合。

In [223]: np.genfromtxt(txt.splitlines(), delimiter=dels, usecols=cols, dtype=None)                    
Out[223]: 
array([(24, 238,  8., 27, 237,  8.), (39,  79,  6., 39,  80,  6.),
       (39,  88,  8., 39,  89,  8.), (39,  97, 10., 39,  98, 10.),
       (39, 104, 12., 39, 105, 12.), (40,  80,  9., 40,  81, 10.),
       (40, 107,  9., 40, 108,  9.), (41,  79,  8., 41,  80,  8.)],
      dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<f8'), ('f3', '<i8'), ('f4', '<i8'), ('f5', '<f8')])

delscols可以扩展为处理所有7个组。

一旦有了这样的数字,就很容易将它们映射到您的最终坐标数组。但是我想你已经解决了。

===

拆分“。”变成自己未使用的列:

In [226]: dels = [2,3,2,1, 3,3,2,1]; cols=[0,1,2, 4,5,6]                                               
In [227]: np.genfromtxt(txt.splitlines(), delimiter=dels, usecols=cols, dtype=int)                     
Out[227]: 
array([[ 24, 238,   8,  27, 237,   8],
       [ 39,  79,   6,  39,  80,   6],
       [ 39,  88,   8,  39,  89,   8],
       [ 39,  97,  10,  39,  98,  10],
       [ 39, 104,  12,  39, 105,  12],
       [ 40,  80,   9,  40,  81,  10],
       [ 40, 107,   9,  40, 108,   9],
       [ 41,  79,   8,  41,  80,   8]])

答案 2 :(得分:0)

要回答我自己的问题:

def slices7(s,pos, *args):
    S=[]
    for length in args:
        S.append(s[pos:pos + length])
        pos += length
    return pos,S

用于,

for h in range(1,8):
    tempLine = basin.readline()
    pos=0
    for k in range(0,7):
        pos,AAA= list(slices7(tempLine,pos,3,3,3))
        try:
            inw = int(AAA[0])
            jnw = int(AAA[1])
            hw = float(AAA[2])
            zbm [inw,jnw] = hw
        except ValueError:
            pass