0

特定の期間における、時間の経過に伴うシグナルの集計平均を計算したいと考えています。これが科学的にどのように呼ばれているかはわかりません。

例: 15 分の値で 1 年間の電力消費量があります。1 日の時間別の平均消費量 (24 値) を知りたいです。しかし、それはより複雑です: 15 分のステップの間にさらに多くの測定値があり、それらがどこにあるかを予測することはできません. ただし、正しい「重み」で考慮に入れる必要があります。

動作する関数を書きましたが、非常に遅いです。テストのセットアップは次のとおりです。

import numpy as np

signal = np.arange(6)
time = np.array([0, 2, 3.5, 4, 6, 8])
period = 4
interval = 2

def aggregate(signal, time, period, interval):
    pass

aggregated = aggregate(signal, time, period, interval)
# This should be the result: aggregated = array([ 2.   ,  3.125])

aggregated値を持つ必要がありperiod/intervalます。これは手動計算です。

aggregated[0] = (np.trapz(y=np.array([0, 1]), x=np.array([0, 2]))/interval + \
               np.trapz(y=np.array([3, 4]), x=np.array([4, 6]))/interval) / (period/interval)
aggregated[1] = (np.trapz(y=np.array([1, 2, 3]), x=np.array([2, 3.5, 4]))/interval + \
                np.trapz(y=np.array([4, 5]), x=np.array([6, 8]))/interval) / (period/interval)

最後の詳細: 効率的でなければならないため、私自身のソリューションは役に立ちません。多分私はnumpyまたはscipyメソッドを見落としていますか? それとも、これはパンダができることですか?どうもありがとうございました。

4

3 に答える 3

4

パンダの使用を強くお勧めします。ここではバージョン0.8を使用しています(まもなくリリースされます)。これはあなたが望むものに近いと思います。

import pandas as p
import numpy as np
import matplotlib as plt

# Make up some data:
time = p.date_range(start='2011-05-23', end='2012-05-23', freq='min')
watts = np.linspace(0, 3.14 * 365, time.size)
watts = 38 * (1.5 + np.sin(watts)) + 8 * np.sin(5 * watts)

# Create a time series
ts = p.Series(watts, index=time, name='watts')

# Resample down to 15 minute pieces, using mean values
ts15 = ts.resample('15min', how='mean')
ts15.plot()

パンダはあなたのデータで他の多くのことを簡単に行うことができます(あなたの平均的な週のエネルギープロファイルを決定するなど)。p.read_csv()データの読み込みを確認してください。

于 2012-05-24T02:30:59.743 に答える
2

これはあなたが必要とするものにかなり近いと思います。interval と period を正しく解釈したかどうかはわかりませんが、一定の範囲内で記述できたと思います。

import numpy as np

def aggregate(signal, time, period, interval):
    assert (period % interval) == 0
    ipp = period / interval

    midpoint = np.r_[time[0], (time[1:] + time[:-1])/2., time[-1]]
    cumsig = np.r_[0, (np.diff(midpoint) * signal).cumsum()]
    grid = np.linspace(0, time[-1], np.floor(time[-1]/period)*ipp + 1)
    cumsig = np.interp(grid, midpoint, cumsig)
    return np.diff(cumsig).reshape(-1, ipp).sum(0) / period
于 2012-05-24T01:55:06.593 に答える
1

以前の回答とパンダに基づいて、私が望んでいたことを正確に実行する関数を作成しました。

def aggregate_by_time(signal, time, period=86400, interval=900, label='left'):
"""
Function to calculate the aggregated average of a timeseries by 
period (typical a day) in bins of interval seconds (default = 900s).

label = 'left' or 'right'.  'Left' means that the label i contains data from 
i till i+1, 'right' means that label i contains data from i-1 till i.    

Returns an array with period/interval values, one for each interval
of the period. 

Note: the period has to be a multiple of the interval

"""

def make_datetimeindex(array_in_seconds, year):
    """
    Create a pandas DateIndex from a time vector in seconds and the year.
    """

    start = pandas.datetime(year, 1, 1)
    datetimes = [start + pandas.datetools.timedelta(t/86400.) for t in array_in_seconds]

    return pandas.DatetimeIndex(datetimes)

interval_string = str(interval) + 'S'    
dr = make_datetimeindex(time, 2012)
df = pandas.DataFrame(data=signal, index=dr, columns=['signal'])
df15min = df.resample(interval_string, closed=label, label=label)

# now create bins for the groupby() method
time_s = df15min.index.asi8/1e9
time_s -= time_s[0]
df15min['bins'] = np.mod(time_s, period)

df_aggr = df15min.groupby(['bins']).mean()

# if you only need the numpy array: take df_aggr.values
return df_aggr 
于 2012-07-06T13:42:29.923 に答える