浮動小数点値である可能性のあるタイムスタンプに従って、データリスト(現在はpandas.DataFrame
)の平均をブロックする必要のあるアプリケーションがあります。例えば、私は0.3
秒のグループに以下のdf
を平均化する必要があるかもしれません:整数duration
のためだけで正常に動作し浮動小数点数のグループ化
import pandas as pd
import numpy as np
def block_avg (df : pd.DataFrame, duration : float) -> pd.DataFrame:
grouping = (df['secs'] - df['secs'][0]) // duration
df = df.groupby(grouping, as_index=False).mean()
df['secs'] = duration * np.arange(1,1+len(df))
return df
:
+------+------+ +------+------+
| secs | A | | secs | A |
+------+------+ +------+------+
| 0.1 | .. | | 0.3 | .. | <-- avg of 0.1, 0.2, 0.3
| 0.2 | .. | --> | 0.6 | .. | <-- avg of 0.4, 0.5, 0.6
| 0.3 | .. | | ... | ... | <-- etc
| 0.4 | .. | +------+------+
| 0.5 | .. |
| 0.6 | .. |
| ... | ... |
+------+------+
は現在、私は、次の(最低限の)ソリューションを使用していますブロックの端の浮動小数点値は間違った側に落ちることがあります。ブロックが適切に作成されているという単純なテストは、データが既に入っている(この例では0.1
)同じduration
で平均化することです。これは入力を返すはずですが、しばしば入力しません。 (例えばx=.1*np.arange(1,20); (x-x[0])//.1)
。)
私はこの方法でエラーが通常であることが分かっているLSB 1が低いので、仮の修正はgrouping
の分子にnp.spacing(df['secs'])
を追加することです。 (つまり、x=.1*np.arange(1,20); all((x-x[0]+np.spacing(x)) // .1 == np.arange(19))
がTrue
を返す)
しかし、これは堅牢な解決策ではないと私は懸念しています。上のテストに合格する浮動小数点数をグループ化するためのより良い、または好ましい方法はありますか?
x[ (duration*i < x) & (x <= duration*(i+1)) ]
を使用してグループ化し、適切な範囲にループi
をグループ化する(おそらくはより簡単な)アルゴリズムで同様の問題が発生しました。
不正確な場合は、msまたはns(つまり、 'np.timedelta')? –
@AndyHayden残念ながら、私はデータの書き方をあまり制御していません。しかし、(今のところ)それは常に1ミリ秒の整数倍であるので、私は '((...)* 1000).astype(int)'にすることができます。 floatが(ほとんど)不正確であることに気づいているので、一方(または両方)の方向に 'np.spacing'を埋め込むことで本当に保証はありませんか? – nivk
そうですね、それはあなたを噛まない不正確なことです。私はあなたが最初にそれを丸めることができると思いますか? –