やりたいこと
深層学習(lstm)で時系列データを扱うのだが、サンプリングレートが高く
シーケンスあたりの情報量が少なそうであったり、学習時にメモリを圧迫したりするので、
いい感じにダウンサンプリングしたい。
サンプルデータ作成
20000フレームの三次元のデータを想定。
処理結果の整合性がとりやすいように単調増加なデータを作成。
npy = np.array([np.arange(1,20000), np.arange(1,20000)*2, np.arange(1,20000)*3]).T
df = pd.DataFrame(npy, columns=["x", "y", "z"])
df
結果
くし型関数っぽくやる
シンプルな方法。データを10フレーム毎に取得する。
t = 10
_df = df.copy()
_df = _df[::t]
_df
結果
任意の幅でデータを取得し平均をとる
任意の窓幅を定義するにはgroupbyを使うと処理が早かった。
以下の例はindexを10で割ったときの商をグループの基準とし、
10サンプルの平均をとることでリサンプリングしている。
t = 10
_df = df.copy()
_df = _df.groupby(_df.index//t).mean()
_df
結果
任意の窓幅でデータを取得し自作関数を適用する
概念は上記の例と同じだが、自作関数を適用するver。
どうやらgroupが複数の列を持つ場合、列ごとに処理を適用する設定らしいので、
関数の入力はseriesとしている。
以下の例は、10サンプル毎の最大値か最小値をランダムに取得し、
リサンプリング結果としている。
def random_choice(series):
npy = series.values
retval = np.random.choice([npy.min(), npy.max()], 1)
return retval
t = 10
_df = df.copy()
_df = _df.groupby(_df.index//t).agg(random_choice)
_df
結果
参照