■目的
300万個のIDそれぞれに対して、1ヶ月分のデータが用意されている
データの中身は、説明変数と目的変数が1つずつ。
つまりテーブルのカラムは、ID、説明変数x、目的変数yの3つ
レコード数は300万×30日 ≒ 9000万
この時、300万のIDそれぞれに対し、30日分の説明変数と目的変数の単回帰を行い、
アウトプットとしてそれぞれのIDに対して相関係数、傾き、p値を格納したい。
##■方針
300万のIDに対し、forループの中で回帰を行い、結果をリストとして格納
最後にリストを結合してデータフレームとする。
この手法の速さに関してはこちらを参照
##■環境
- EC2インスタンス(ubuntu: r5d.4xlarge)
- JupyterLab 0.35.3
##■課題
単純にデータフレームから各IDに対応するレコードをクエリ抽出すると、時間がかかる(1idあたり約13秒)
for id in id_list:
tmp_x = df[df.id == id].x
tmp_y = df[df.id == id].y
##■解決策
- idをindexにしdf.loc[]で抽出することで高速化 (1idあたり約3.9秒)
df.index = df.id
for id in id_list:
tmp_x = df.loc[id].x
tmp_y = df.loc[id].y
- 上記と合わせて、pandasデータフレームの代わりにdaskデータフレームを使用 (1idあたり1.7秒)
※daskとはなんぞや
import dask.dataframe as dd
import multiprocessing
df.index = df.id
# 現環境では cpu_count = 32
ddf = dd.from_pandas(df, npartitions=multiprocessing.cpu_count())
for id in id_list:
tmp_x = ddf.loc[id].x.compute()
tmp_y = ddf.loc[id].y.compute()
##■結論
まだ遅い。これだと全データの処理が完了するのに2ヶ月かかってしまう。。
##■今後の予定
現状、1つのIDにつき30レコードが格納されている状況であるのを、30日分のデータをリストとして1セルに格納することで1IDにつき1レコードにする
こうすることで、ループ処理に内包処理が使用できるため、処理速度の向上が望める可能性がある。
(ただしそもそも30レコード → 1レコードへの変換にどれだけ時間がかかるか。。。 pivot_tableですんなりいってほしい)