时间序列平均与python

时间:2013-04-14 20:59:32

标签: python pandas time-series

我看着熊猫,为了我的目的,它可能并不容易。 可能有一个python工具包在那里,我不知道。 你能告诉我哪个包可以轻松处理下面描述的情况吗?

我有一系列2D numpy数组即时值的气象变量(对于一个地理区域),在0,6,12,......,96,......的特定日期采样。

我把它作为python词典:

values[0]:[[3, 2,...,9, 5][6, 7, ..., 6, 7]]
...
...
values[96]:[[2, 2,...,8, 5][6, 7, ..., 5, 6]]

我需要对可配置的聚合步骤进行平均。例如,对于24小时的聚合步骤,我将获得4个每日平均值:

values_avg24h=average(values, aggr_step=24)
values_avg24h[24]=[[...][...]]
values_avg24h[48]=[[...][...]]
values_avg24h[72]=[[...][...]]
values_avg24h[96]=[[...][...]]

时间分辨率可能会发生变化。此外,原始值也可以平均,但​​在不同的聚合步骤。特定的现有包可以解决所有这些问题。无论如何,即使是这个简单问题的智能解决方案也会受到赞赏。

2 个答案:

答案 0 :(得分:2)

import numpy as np

def average(values, aggr_step=24):
    keys = np.array(values.keys())
    bins = range(aggr_step,1+keys.max(),aggr_step)
    npd = np.digitize(keys,bins)
    return {b:np.mean(np.r_[[values[k] for k in keys[npd==i]]],axis=0)
            for i,b in enumerate(bins)}

掀起一些样本值,并测试:

values = {h:np.array([np.random.random_integers(1,10,5) for _ in 'x'*2])
          for h in np.r_[0:100:6]}

{0: array([[ 1,  2, 10,  8,  7],
       [10,  1,  8,  2,  5]]),
 6: array([[ 7, 10,  7,  6,  4],
       [ 9,  4,  6,  1,  1]]),
 12: array([[ 7, 10, 10,  5,  4],
       [ 7,  6,  2,  6,  7]]),
 18: array([[9, 9, 8, 5, 8],
       [8, 9, 6, 1, 2]]),
 24: array([[8, 1, 5, 9, 7],
       [1, 1, 6, 8, 3]]),
 30: array([[ 7,  2,  8,  3,  4],
       [ 5, 10,  5,  6,  5]]),
 36: array([[ 6,  5,  9,  4,  5],
       [ 6, 10,  8, 10, 10]]),
 42: array([[ 2,  2,  6,  6,  9],
       [ 5,  7,  4,  8, 10]]),
 48: array([[10,  1,  1,  1,  8],
       [ 5,  6,  4,  5,  8]]),
 54: array([[ 6,  2,  6,  6,  6],
       [10,  6,  9,  4,  8]]),
 60: array([[ 6,  8,  2,  1,  7],
       [ 1, 10, 10,  2,  3]]),
 66: array([[4, 8, 7, 1, 3],
       [1, 3, 8, 4, 2]]),
 72: array([[ 8,  9,  8,  6,  7],
       [ 1,  4,  2, 10,  1]]),
 78: array([[ 2,  1,  3,  8,  9],
       [ 2,  8,  6, 10,  3]]),
 84: array([[ 1,  8,  9,  4,  3],
       [ 9, 10,  8,  3,  4]]),
 90: array([[ 4,  4,  2,  8,  6],
       [ 1,  3, 10,  2,  6]]),
 96: array([[ 9,  9,  8,  4,  4],
       [ 2,  8, 10,  3,  5]])}

average(values,24)

{24: array([[ 6.  ,  7.75,  8.75,  6.  ,  5.75],
       [ 8.5 ,  5.  ,  5.5 ,  2.5 ,  3.75]]),
 48: array([[ 5.75,  2.5 ,  7.  ,  5.5 ,  6.25],
       [ 4.25,  7.  ,  5.75,  8.  ,  7.  ]]),
 72: array([[ 6.5 ,  4.75,  4.  ,  2.25,  6.  ],
       [ 4.25,  6.25,  7.75,  3.75,  5.25]]),
 96: array([[ 3.75,  5.5 ,  5.5 ,  6.5 ,  6.25],
       [ 3.25,  6.25,  6.5 ,  6.25,  3.5 ]])}

答案 1 :(得分:2)

如果数据是以常规频率(您的帖子似乎表明)采样的,那么pandas当然可以帮助您。

一种可能的pandas解决方案是创建一个Panel对象,其中items(与字典中的键一样)属于类pandas.tseries.index.DatetimeIndexmajor_axis的{​​{1}}和minor_axis元素将成为numpy数组中的行和列。这听起来有点奇怪,所以我将展示一个简单的例子。

Panel

现在我们已经设置好了,我们将使用>>> import pandas as pd >>> import numpy as np >>> start_date = '4/14/2013' # Start today (default time is midnight) # create the date_range we will use as panel items >>> ind = pd.date_range(start=start_date, periods=20, freq='6H') # Create data: thanks @mtadd >>> values = {h:np.array([np.random.random_integers(1,10,5) for _ in 'x'*2]) for h in np.r_[0:120:6]} # Create the Panel object directly from the dict of 2D np.arrays >>> my_panel = pd.Panel(values) # Set the Panel's items to be the date_range we made earlier >>> my_panel.items = ind >>> my_panel.ix[0] # Show first 2D array of data 0 1 2 3 4 0 4 3 10 6 6 1 4 10 7 10 6 >>> values[0] # Same as above, but from the dict array([[ 4, 3, 10, 6, 6], [ 4, 10, 7, 10, 6]]) 方法Panel。我们将提供两个参数,第一个是我们希望数据处于的新频率,第二个是我们将指定为resample的关键字参数how 这是我答案的主要部分!

mean

请注意,我们提供>>> averaged = my_panel.resample('24H', how='mean') >>> list(averaged.items) # Show new time stamps for data [<Timestamp: 2013-04-14 00:00:00>, <Timestamp: 2013-04-15 00:00:00>, <Timestamp: 2013-04-16 00:00:00>, <Timestamp: 2013-04-17 00:00:00>, <Timestamp: 2013-04-18 00:00:00>] 方法的'24H'参数只是OA发布的示例的扩展。有关此参数可采用何种类型的描述的详细信息,请参阅this link

要验证平均值是否正确计算,我们会将resample averaged中的第一项与我们手动计算的平均值进行比较。

Panel

如果您传递>>> averaged.ix[0] 0 1 2 3 4 0 6.5 5.25 7.25 6.25 6.50 1 5.0 6.75 5.25 6.50 5.25 >>> (values[0] + values[6] + values[12] + values[18]) / 4. array([[ 6.5 , 5.25, 7.25, 6.25, 6.5 ], [ 5. , 6.75, 5.25, 6.5 , 5.25]]) 对象,则items的时间戳可以更灵活。例如,如果您在新年元旦下午1:37开始抽样并继续抽样50个时间你可以这样做:

datetime.datetime

然后你会像以前一样继续。您还可以将开始和结束项目传递给date_range,而不是您希望它生成的句点数。如果我们从上述相同的开始时间每2个半小时收集数据,直到2月28日凌晨4:50,您可以执行以下操作:

>>> from datetime import datetime
>>> start = datetime(2013, 1, 1, 13, 37)  # 1:37 on 1/1/2013
>>> ind = pd.date_range(start, periods=50, freq='6H')

请注意,您不必传递与传入频率完全一致的开始和结束时间。有关如何使用Panel对象或time series data {{3}}的更多详细信息。 1}}查看这些单词中给出的链接。