Python:从CSV读取时间步到数组:使用NumPy后处理模型数据;

1 投票
2 回答
1237 浏览
提问于 2025-04-18 09:47

我还在努力学习Python,但这个问题超出了我的知识范围:

主题:水动力后处理:

将水力软件的CSV输出转换为数组,分割时间步长。

这里是数据和我目前写出的代码:

输入文件(见下文):

第一行:结果节点的数量

第二行:标题

第三行:时间步长 @ 时间=

接下来:这个时间步长的所有结果(在这个文件中:13541个节点,变量)

……接下来是下一个时间步长的相同内容。

# Number of Nodes: 13541
#X                  Y                   Z                   depth               wse             
# Output at t = 0
       5603.7598           4474.4902           37.470001                   0           37.470001
          5610.5           4461.6001           36.020001                   0           36.020001
         5617.25             4448.71           35.130001                   0           35.130001
       5623.9902           4435.8198               35.07                   0               35.07
       5630.7402           4422.9199               35.07                   0               35.07
       5761.5801             4402.79           35.369999                   0           35.369999
COMMENT:....................13541 timesteps...........
# Output at t = 120.04446
       5603.7598           4474.4902           37.470001           3.6977223           41.167724
          5610.5           4461.6001           36.020001           4.1377293            40.15773
         5617.25             4448.71           35.130001           3.9119012           39.041902
       5623.9902           4435.8198               35.07           3.7923947           38.862394
       5630.7402           4422.9199               35.07            3.998436           39.068436
       5761.5801             4402.79           35.369999           3.9750571           39.345056
COMMENT:....................13541 timesteps...........
# Output at t = 240.06036
       5603.7598           4474.4902           37.470001           11.131587           48.601588
          5610.5           4461.6001           36.020001           12.564266           48.584266
         5617.25             4448.71           35.130001           13.498463           48.628464
       5623.9902           4435.8198               35.07           13.443041           48.513041
       5630.7402           4422.9199               35.07           11.625824           46.695824
       5761.5801             4402.79           35.369999            19.49551           54.865508

问题:

我需要一个循环,把n个时间步长读入数组。

结果应该是:每个时间步长对应一个数组:在这个例子中,有27个时间步长,每个都有13541个元素。

timestep_1=[这个时间步长的所有元素:形状=13541,5]

timestep_2=[]

timestep_3=[]

........

timestep_n=[]

到目前为止我的代码:

 import numpy as np
 import csv
 from numpy import *
 import itertools

 #read file to big array
 array=np.array([row for row in csv.reader(open("ascii-full.csv", "rb"), delimiter='\t')])      
 firstRow=array[0]
 secondRow=array[1]

 # find out how many nodes
 strfirstRow=' '.join(map(str,firstRow))
 first=strfirstRow.split()
 print first[4]
 nodes=first[4]
 nodes=float(nodes)

 #count timesteps
 temp=(len(array)-3)/nodes           
 timesteps=int(temp)+1

 #split array into timesteps:
 # X Y Z h(t1) h(t2) h(tn)

 ts1=array[3:nodes+3]#13541
 #print ts1

 ts2=array[nodes+4:nodes*2+4]
 #print ts2


 .......
 read ts3 to last timestep to arrays with loop....

也许有人可以帮我,谢谢!!!

2 个回答

1

你可以使用 np.genfromtxt() 来获取一个三维数组,像这样:

import numpy as np

gen = (a for a in open('test.txt') if not a[0] in ['#', 'C'])
a = np.genfromtxt(gen).reshape(-1, 6, 5)

其中 a[i] 表示在时间步 i 时的输出结果。

0

我对你的问题的看法是,不要把整个文件一次性读进一个数组里再处理,而是应该一行一行地读取,边读边创建数组。

我会先读取每个时间点的行数和列数,然后为每个读取的时间点创建一个新的数组(把它加到一个列表里),接着用读取到的数据填充这个数组。

import numpy as np

timesteps = []
timestep_results = []

f = open("ascii-full.csv", "rb")

# First line is number of rows (not counting the initial #)
rows = int(f.readline().strip()[1:].split()[-1])
counter = 0

# Second line is number of columns
columns = len(f.readline().strip().split())

# Next lines
for line in f:
    if line.startswith("#"):
        # it's a header: add time to timestep list, begin new array
        timesteps.append( float(line.strip().split("=")[1]) )
        timestep_results.append( np.zeros((rows, columns)) )
        counter = 0
    else:
        # it's data: add to array in appropiate row
        timestep_results[-1][counter] = map(float, line.strip().split())
        counter += 1

f.close()

希望这对你有帮助!

撰写回答