快速抽样numpy数组切片的方法是什么?

5 投票
2 回答
963 浏览
提问于 2025-04-17 04:45

我有一个三维的numpy数组,里面存储了几年的(比如5年)每6小时的时间序列数据。现在我想随机从这些记录中选出每个日历日的一条数据,形成一个新的时间序列。具体来说,就是每天从5个可能的记录中随机选一个,像这样:

  • 2006年1月1日
  • 2011年1月2日
  • 2009年1月3日
  • ...

这意味着我需要从2006年1月1日选出4个值,从2011年1月2日选出4个值,依此类推。

我现在有一个可行的办法,步骤如下:

  • 先把输入的数组调整形状,增加一个“年份”的维度(时间,年份,X,Y)
  • 创建一个包含365个随机整数的数组,这些整数在0到4之间
  • 使用np.repeat和这个整数数组来提取相关的值:

示例:

sampledValues = Variable[np.arange(numberOfDays * ValuesPerDays), sampledYears.repeat(ValuesPerDays),:,:]

这个方法似乎有效,但我在想,这是否是解决我问题的最佳或最快的方法?因为我在循环中执行这个操作,速度很重要,我希望能测试尽可能多的情况。

我这样做对吗?

谢谢

编辑

我忘了提到,我已经过滤掉了闰年的2月29日。

基本上,这个操作的目的是找到一个365天的样本,使其在均值等方面与长期时间序列匹配得很好。如果这个抽样的时间序列通过了我的质量测试,我想把它导出,然后重新开始。

2 个回答

0

我觉得没必要重新调整这个数组的形状,因为你可以在采样的过程中直接把年份的信息包含进去,这样数组就可以保持原来的形状。

比如,你可以生成一个随机的偏移量(从0到365之间),然后用这个偏移量来选择数组的一部分,假设你用的索引是 n*365 + offset

不过,我觉得你的问题不太完整,因为我不太明白你到底想做什么,或者为什么要这么做。

3

2008年有366天,所以不要改变它的形状。

可以看看这个链接:scikits.timeseries

import scikits.timeseries as ts

start_date = ts.Date('H', '2006-01-01 00:00')
end_date = ts.Date('H', '2010-12-31 18:00')
arr3d = ... # your 3D array [time, X, Y]

dates = ts.date_array(start_date=start_date, end_date=end_date, freq='H')[::6]
t = ts.time_series(arr3d, dates=dates)
# just make sure arr3d.shape[0] == len(dates) !

现在你可以用天/月/年的对象来访问t的数据了:

t[np.logical_and(t.day == 1, t.month == 1)]

比如说:

for day_of_year in xrange(1, 366):
    year = np.random.randint(2006, 2011)

    t[np.logical_and(t.day_of_year == day_of_year, t.year == year)]
    # returns a [4, X, Y] array with data from that day

可以试着调整t的属性,让它也能适应闰年。

撰写回答