【问题标题】:Pandas computer hourly average and set at middle of intervalPandas 计算机每小时平均值并设置在中间间隔
【发布时间】:2016-11-04 20:57:59
【问题描述】:

我想计算风速和风向时间序列的每小时平均值,但我想将时间设置为半小时。因此,从 14:00 到 15:00 的平均值为 14:30。现在,我似乎只能在间隔的左侧或右侧得到它。这是我目前拥有的:

ts_g=[item.replace(second=0, microsecond=0) for item in dates_g]
dg = {'ws': data_g.ws, 'wdir': data_g.wdir}
df_g = pandas.DataFrame(data=dg, index=ts_g, columns=['ws','wdir'])
grouped_g = df_g.groupby(pandas.TimeGrouper('H'))
hourly_ws_g = grouped_g['ws'].mean()
hourly_wdir_g = grouped_g['wdir'].mean()

这个输出看起来像:

2016-04-08 06:00:00+00:00     46.980000
2016-04-08 07:00:00+00:00     64.313333
2016-04-08 08:00:00+00:00     75.678333
2016-04-08 09:00:00+00:00    127.383333
2016-04-08 10:00:00+00:00    145.950000
2016-04-08 11:00:00+00:00    184.166667
....

但我希望它是这样的:

2016-04-08 06:30:00+00:00     54.556
2016-04-08 07:30:00+00:00     78.001
....

感谢您的帮助!

【问题讨论】:

    标签: python pandas time-series


    【解决方案1】:

    所以最简单的方法是重新采样,然后使用线性插值:

    In [21]: rng = pd.date_range('1/1/2011', periods=72, freq='H')
    
    In [22]: ts = pd.Series(np.random.randn(len(rng)), index=rng)
        ...: 
    
    In [23]: ts.head()
    Out[23]: 
    2011-01-01 00:00:00    0.796704
    2011-01-01 01:00:00   -1.153179
    2011-01-01 02:00:00   -1.919475
    2011-01-01 03:00:00    0.082413
    2011-01-01 04:00:00   -0.397434
    Freq: H, dtype: float64
    
    In [24]: ts2 = ts.resample('30T').interpolate()
    
    In [25]: ts2.head()
    Out[25]: 
    2011-01-01 00:00:00    0.796704
    2011-01-01 00:30:00   -0.178237
    2011-01-01 01:00:00   -1.153179
    2011-01-01 01:30:00   -1.536327
    2011-01-01 02:00:00   -1.919475
    Freq: 30T, dtype: float64
    
    In [26]: 
    

    我相信这就是你所需要的。

    编辑以添加澄清示例

    也许没有随机数据更容易看到发生了什么:

    In [29]: ts.head()
    Out[29]: 
    2011-01-01 00:00:00    0
    2011-01-01 01:00:00    1
    2011-01-01 02:00:00    2
    2011-01-01 03:00:00    3
    2011-01-01 04:00:00    4
    Freq: H, dtype: int64
    
    In [30]: ts2 = ts.resample('30T').interpolate()
    
    In [31]: ts2.head()
    Out[31]: 
    2011-01-01 00:00:00    0.0
    2011-01-01 00:30:00    0.5
    2011-01-01 01:00:00    1.0
    2011-01-01 01:30:00    1.5
    2011-01-01 02:00:00    2.0
    Freq: 30T, dtype: float64
    

    【讨论】:

      【解决方案2】:

      这篇文章已经有几年的历史了,并且使用了早已被弃用的 API。 Modern Pandas 已经提供了resample 方法,它比pandas.TimeGrouper 更易于使用。然而,它只允许 leftright 标记的区间,但让区间居中在区间的中间并不容易。

      但这并不难做到。

      首先我们填写要重采样的数据:

      ts_g=[datetime.datetime.fromisoformat('2019-11-20') + 
            datetime.timedelta(minutes=10*x) for x in range(0,100)]
      dg = {'ws': range(0,100), 'wdir': range(0,100)}
      
      df_g = pd.DataFrame(data=dg, index=ts_g, columns=['ws','wdir'])
      df_g.head()
      

      输出将是:

                             ws   wdir
      2019-11-20 00:00:00     0   0
      2019-11-20 00:10:00     1   1
      2019-11-20 00:20:00     2   2
      2019-11-20 00:30:00     3   3
      2019-11-20 00:40:00     4   4
      

      现在我们首先重新采样到 30 分钟的间隔

      grouped_g = df_g.resample('30min')
      halfhourly_ws_g = grouped_g['ws'].mean()
      halfhourly_ws_g.head()
      

      输出将是:

      2019-11-20 00:00:00     1
      2019-11-20 00:30:00     4
      2019-11-20 01:00:00     7
      2019-11-20 01:30:00    10
      2019-11-20 02:00:00    13
      Freq: 30T, Name: ws, dtype: int64
      

      最后获得居中间隔的技巧:

      hourly_ws_g = halfhourly_ws_g.add(halfhourly_ws_g.shift(1)).div(2)\
                                   .loc[halfhourly_ws_g.index.minute % 60 == 30]
      hourly_ws_g.head()
      

      这将产生预期的输出:

      2019-11-20 00:30:00     2.5
      2019-11-20 01:30:00     8.5
      2019-11-20 02:30:00    14.5
      2019-11-20 03:30:00    20.5
      2019-11-20 04:30:00    26.5
      Freq: 60T, Name: ws, dtype: float64
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-01
        • 1970-01-01
        相关资源
        最近更新 更多