滚动平均计算降雨强度

2 投票
2 回答
2667 浏览
提问于 2025-04-17 07:13

我有一些真实的降雨数据,这些数据记录了日期和时间,还有一个翻斗雨量计的累计滴水次数。这个翻斗雨量计每次翻转代表0.5毫米的降雨量。我想遍历这个文件,计算降雨强度的变化(降雨量/时间)。

所以我需要在多个固定时间段内计算滚动平均值:我想累积降雨量,直到累计到5分钟的降雨量,然后计算出降雨强度,单位是毫米/小时。比如说,如果在5分钟内记录到3毫米的降雨量,那就是3/5*60 = 36毫米/小时。如果在10分钟内降雨量是相同的,那强度就是18毫米/小时……

如果我有几小时的降雨数据,我可能需要在几个标准时间间隔内进行查看,比如:5分钟、10分钟、15分钟、20分钟、25分钟、30分钟、45分钟、60分钟等等……

另外,原始文件中的数据是反向记录的,也就是说最早的时间在文件的最后,而最新的时间在文件的开头,紧接着是一个标题。看起来像这样……(这里975 - 961 = 14次翻斗 = 7毫米的降雨量)平均强度是1.4毫米/小时。但是在16:27到16:34之间,967-961 = 6次翻斗 = 3毫米的降雨量,时间是7分钟,强度是27.71毫米/小时。

7424 Figtree (O'Briens Rd)
DATE     :hh:mm Accum Tips
8/11/2011 20:33     975
8/11/2011 20:14     974
8/11/2011 20:04     973
8/11/2011 20:00     972
8/11/2011 19:35     971
8/11/2011 18:29     969
8/11/2011 16:44     968
8/11/2011 16:34     967
8/11/2011 16:33     966
8/11/2011 16:32     965
8/11/2011 16:28     963
8/11/2011 16:27     962
8/11/2011 15:30     961

有什么建议吗?

2 个回答

0

因为时间戳不是按固定间隔出现的,所以你应该使用插值法来获得更准确的结果。这样计算滚动平均值也会更简单。我在下面的代码中使用了Interpolate类,具体可以参考这个回答

from time import strptime, mktime

totime = lambda x: int(mktime(strptime(x, "%d/%m/%Y %H:%M")))
with open("my_file.txt", "r") as myfile:
    # Skip header
    for line in myfile:
        if line.startswith("DATE"):
            break
    times = []
    values = []
    for line in myfile:
        date, time, value = line.split()
        times.append(totime(" ".join((date, time))))
        values.append(int(value))
times.reverse()
values.reverse()
i = Interpolate(times, values)

现在只需要选择你的时间间隔,并计算每个间隔的起始点和结束点之间的差值。我们来创建一个生成器函数来实现这个功能:

def rolling_avg(cumulative_lookup, start, stop, step_size, window_size):
    for t in range(start + window_size, stop, step_size):
        total = cumulative_lookup[t] - cumulative_lookup[t - window_size]
        yield total / window_size

下面我打印的是前一个小时每小时的提示数量,时间间隔为10分钟:

start = totime("8/11/2011 15:30")
stop = totime("8/11/2011 20:33")
for avg in rolling_avg(i, start, stop, 600, 3600):
    print avg * 3600

编辑:totime的返回值改为整数,并创建了rolling_avg生成器。

1

我不太确定你具体想问什么。

你知道怎么读取文件吗?你可以这样做:

data = [] # Empty list of counts

# Skip the header
lines = [line.strip() for line in open('data.txt')][2::]

for line in lines:
    print line
    date, hour, count = line.split()
    h,m = hour.split(':')
    t = int(h) * 60 + int(m)      # Compute total minutes
    data.append( (t, int(count) ) ) # Append as tuple

data.reverse()

因为你的数据是累积的,所以你需要把每两个数据项相减,这时候用Python的列表推导式就特别方便。

data = [(t1, d2 - d1) for ((t1,d1), (t2, d2)) in zip(data, data[1:])]
print data

现在我们需要循环查看在最近的x分钟内有多少条数据。

timewindow = 10
for i, (t, count) in enumerate(data):
    # Find the entries that happened within the last [...] minutes
    withinwindow = filter( lambda x: x[0] > t - timewindow, data )
    # now you can print out any kind of stats about this "within window" entries
    print sum( count for (t, count) in withinwindow )

撰写回答