次の2つのベクトルがあるとします。
In [99]: time_index
Out[99]:
[1484942413,
1484942712,
1484943012,
1484943312,
1484943612,
1484943912,
1484944212,
1484944511,
1484944811,
1484945110]
In [100]: bytes_in
Out[100]:
[1293981210388,
1293981379944,
1293981549960,
1293981720866,
1293981890968,
1293982062261,
1293982227492,
1293982391244,
1293982556526,
1293982722320]
ここで、bytes_inは増分のみのカウンターであり、time_indexはUNIXタイムスタンプ(エポック)。
目的:計算したいのはビットレートです。
つまり、次のようなデータフレームを作成します。
In [101]: timeline = pandas.to_datetime(time_index, unit="s")
In [102]: recv = pandas.Series(bytes_in, timeline).resample("300S").mean().ffill().apply(lambda i: i*8)
In [103]: recv
Out[103]:
2017-01-20 20:00:00 10351849683104
2017-01-20 20:05:00 10351851039552
2017-01-20 20:10:00 10351852399680
2017-01-20 20:15:00 10351853766928
2017-01-20 20:20:00 10351855127744
2017-01-20 20:25:00 10351856498088
2017-01-20 20:30:00 10351857819936
2017-01-20 20:35:00 10351859129952
2017-01-20 20:40:00 10351860452208
2017-01-20 20:45:00 10351861778560
Freq: 300S, dtype: int64
質問:さて、奇妙なことに、勾配を手動で計算すると次のようになります。
In [104]: (bytes_in[1]-bytes_in[0])*8/300
Out[104]: 4521.493333333333
これは正しい値です。
pandasで勾配を計算しながら
In [124]: recv.diff()
Out[124]:
2017-01-20 20:00:00 NaN
2017-01-20 20:05:00 1356448.0
2017-01-20 20:10:00 1360128.0
2017-01-20 20:15:00 1367248.0
2017-01-20 20:20:00 1360816.0
2017-01-20 20:25:00 1370344.0
2017-01-20 20:30:00 1321848.0
2017-01-20 20:35:00 1310016.0
2017-01-20 20:40:00 1322256.0
2017-01-20 20:45:00 1326352.0
Freq: 300S, dtype: float64
上記とは異なり、1356448.0は4521.493333333333とは異なります
私が間違っていることを教えてください。
pd.Series.diff()
は違いのみを受け取ります。インデックスのデルタでも除算しません。
これで答えが得られます
recv.diff() / recv.index.to_series().diff().dt.total_seconds()
2017-01-20 20:00:00 NaN
2017-01-20 20:05:00 4521.493333
2017-01-20 20:10:00 4533.760000
2017-01-20 20:15:00 4557.493333
2017-01-20 20:20:00 4536.053333
2017-01-20 20:25:00 4567.813333
2017-01-20 20:30:00 4406.160000
2017-01-20 20:35:00 4366.720000
2017-01-20 20:40:00 4407.520000
2017-01-20 20:45:00 4421.173333
Freq: 300S, dtype: float64
numpy.gradient
を使用して、bytes_in
と必要なデルタを渡すこともできます。これは、長さを1つ減らすことはせず、代わりにエッジに関する仮定を行います。
np.gradient(bytes_in, 300) * 8
array([ 4521.49333333, 4527.62666667, 4545.62666667, 4546.77333333,
4551.93333333, 4486.98666667, 4386.44 , 4387.12 ,
4414.34666667, 4421.17333333])
Pandas Series/DataFrameには組み込みのderivative
メソッドがないため、使用できます https://github.com/scls19fr/pandas-helper-calc =。
calc
と呼ばれる新しいアクセサーをPandas= SeriesおよびDataFramesに提供して、数値微分および積分を計算します。
だからあなたは簡単にできるようになります
_recv.calc.derivative()
_
内部でdiff()
を使用しています。
素朴な説明は、np.gradientが中央差分スキームを使用している間にdiffが文字通り後続のエントリを減算するということです。