1

我正在使用校准软件 PEST 中的一个实用程序,该实用程序仅与示例站点文件类型兼容。我想使用这个实用程序来校准我的模型,但是我的模型的输出是一种非常不同的格式 (CSV)。SSF 是制表符分隔的,仅包含 4 个关键数据列:示例站点 ID、日期 (MM/DD/YYYY)、时间和流。

SSF 文件示例:

134 01/01/1980 00:00:00 34
134 01/02/1980 00:00:00 30
134 01/03/1980 00:00:00 28
134 01/04/1980 00:00:00 38

我的水文模型的输出被写入 CSV 文件,其中包含日期 (YYYYMMDD)、模拟流量 (Qsim)、观测流量 (Qobs)、温度、降水量、实际蒸发量、潜在蒸发量和雪水当量。

模型输出示例:

134
Date, Qsim, Qobs, Temp, Precip, AET, PET, SWE
19800101, 34, 31, 11, 21, 3.4, 4.0, 0
19800102, 30, 30, 11, 15, 3.0, 4.4, 0
19800103, 28, 25, 12, 0, 3.1, 4.0, 0
19800104, 38, 45, 8, 30, 0.5, 3.8, 0

因此,我确定为了进行转换,我将:

  1. 添加包含站点 ID 的第 0 列(csv 文件中的第 0 行)
  2. 删除 csv 文件中的第 0 行和第 1 行
  3. 删除 csv 文件中的第 2-7 行
  4. 为时间添加一列(在这种情况下,我只需要在 col 2 中为每一行添加“00:00:00”)
  5. 将日期从 YYYYMMDD 重新格式化为 MM/DD/YYYY
  6. 写入文件制表符分隔

我绝对是 python 的初学者,这是我迄今为止能够编写的代码:

import csv
HBVout = csv.reader(open('C:\\ENVpest\\Output\\Results.csv', 'rb'))
HBVout.next()
newSSF = csv.writer(open('SSF1.txt', 'wb+'), delimiter='\t')

for cline in HBVout:
    new_line = [val for col, val in enumerate(cline) if col not in (2,3,4,5,6,7)]
    newSSF.writerow(new_line)

我可以跳过第一行,删除不必要的列,然后重写为制表符分隔的文件。对于向文件添加列和重新格式化日期的任何帮助,我将不胜感激!我已经在 SO 和其他网站上搜索了其他问题,但还没有找到任何运气。

4

2 回答 2

1

使用内置datetime模块可以很容易地重新格式化日期,如下所示:

from datetime import datetime
d = datetime.strptime("19800508", "%Y%m%d")  # convert your string to a 
                                             # datetime object
s = d.strftime("%d/%m/%Y")  # gives the string "08/05/1980"

诚然,这个模块使用起来有点令人困惑——我总是在使用它之前查看文档——但它非常强大。处理日期转换不是一个人想要手动完成的事情。

我对该模块没有太多经验,csv但我认为您走在正确的轨道上。

于 2013-10-16T01:56:18.297 回答
1

这就是我将如何做到的。您的代码起初有点令人困惑,因为它正在读取您正在调用的另一个程序的输出HBVout。我也不明白你在#3 中关于删除 csv 文件中的第 2-7 行的意思,所以忽略了它。虽然该datetime模块可以用来转换日期的格式,但它非常简单,只能手动完成。

一个显着的区别是使用 a 读取数据,csv.DictReader因为这使得访问各个字段更具可读性,因为读取的每一行都变成了值的字典。

import csv

with open('Results.csv', 'rb') as inf, open('SSF1.txt', 'wb') as outf:
    site_id = inf.next().rstrip()  # read past site id on first line
    HBVout = csv.DictReader(inf, skipinitialspace=True)  # will read header line
    ssf = csv.writer(outf, delimiter='\t')

    for data in HBVout:
        date = data['Date']  # convert date from YYYYMMDD to MM/DD/YYYY 
        date = '/'.join((date[4:6], date[6:8], date[0:4]))
        ssf.writerow([site_id, date, '00:00:00', data['Qsim']])

从模型输出示例创建的 SSF 文件的内容:

134\t01/01/1980\t00:00:00\t34\n
134\t01/02/1980\t00:00:00\t30\n
134\t01/03/1980\t00:00:00\t28\n
134\t01/04/1980\t00:00:00\t38\n
于 2013-10-16T02:31:52.557 回答