我正在尝试使用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
这仅返回每行的第一组值,并且不会遍历整行。有没有办法让它在一行中遍历每组数字?也许有另一种方法可以做到?
答案 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')])
dels
和cols
可以扩展为处理所有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