data
下記のようなdataframeがあります。
(実際のデータは数千万行のデータになります)
範囲指定で
日付 | 時間 | price |
---|---|---|
2020-11-01 | 9:00 | 10 |
2020-11-01 | 10:00 | 20 |
2020-11-01 | 11:00 | 30 |
2020-11-01 | 12:00 | 40 |
2020-11-01 | 13:00 | 50 |
2020-11-02 | 9:00 | 100 |
2020-11-02 | 10:00 | 200 |
2020-11-02 | 11:00 | 300 |
2020-11-02 | 12:00 | 400 |
2020-11-02 | 13:00 | 500 |
2020-11-03 | 9:00 | 110 |
2020-11-03 | 10:00 | 120 |
2020-11-03 | 11:00 | 130 |
2020-11-03 | 12:00 | 140 |
2020-11-03 | 13:00 | 150 |
やりたいこと
日毎に前日までのpriceの標準偏差を算出したい。
欲しい結果
日付 | 標準偏差 |
---|---|
2020-11-02 | 15.8113883 |
2020-11-03 | 177.40412 |
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
集合を結合したときの分散は、もとの集合の要素数、平均、分散がわかっていれば計算しなおせます。
(combine stdevとかで検索してみてください)
なので、日付でgroupbyして、要素数、平均、分散を計算しておけば、それらから複数日に対しての分散が計算できます。
下記では、式を変形して累計和(cumsum)で、前日までの標準偏差を計算するようにしてみました。
python
1import pandas as pd 2import numpy as np 3 4df = ... 5 6df2 = df.groupby('日付')['price'].agg(['count', 'mean', 'var']) 7n = df2['count'] 8m = df2['mean'] 9v = df2['var'] 10 11N = n.cumsum().shift() 12M = (n * m).cumsum().shift() / N 13V = v * (n - 1) + (np.square(m - M) / (1 / N + 1 / n)).fillna(0.0) 14V = V.cumsum().shift() / (N - 1) 15 16stdev = np.sqrt(V).rename('標準偏差').to_frame() 17print(stdev) 18# 標準偏差 19#日付 20#2020-11-01 NaN 21#2020-11-02 15.811388 22#2020-11-03 177.404121
数千万行のデータで動くかは未検証です。
投稿2021/10/19 11:55
総合スコア4794
0
質問のようなケースなら逐次的に計算するとよいでしょう。
参考:分散の逐次更新
具体的にはwelfordを使うと以下のように計算でき
日付の切り替わり毎にそれまでの値を出力すればよいです。
Python
1 2import pandas as pd 3from io import StringIO 4import math 5import numpy as np 6from welford import Welford 7 8s = """日付,時間,price 92020-11-01,9:00,10 102020-11-01,10:00,20 112020-11-01,11:00,30 122020-11-01,12:00,40 132020-11-01,13:00,50 142020-11-02,9:00,100 152020-11-02,10:00,200 162020-11-02,11:00,300 172020-11-02,12:00,400 182020-11-02,13:00,500 192020-11-03,9:00,110 202020-11-03,10:00,120 212020-11-03,11:00,130 222020-11-03,12:00,140 232020-11-03,13:00,150""" 24df = pd.read_csv(StringIO(s)) 25df['date'] = pd.to_datetime( df['日付'] + ' ' + df['時間']) 26df = df.loc[:,['date','price']] 27 28row = [] 29w = Welford() 30for v in df['price']: 31 w.add(np.array(v)) 32 row.append([w.mean, math.sqrt(w.var_s)]) 33 34row = np.array(row) 35df['mean'] = row[:,0] 36df['std'] = row[:,1] 37print(df) 38""" 39 date price mean std 400 2020-11-01 09:00:00 10 153.333333 NaN 411 2020-11-01 10:00:00 20 153.333333 7.071068 422 2020-11-01 11:00:00 30 153.333333 10.000000 433 2020-11-01 12:00:00 40 153.333333 12.909944 444 2020-11-01 13:00:00 50 153.333333 15.811388 455 2020-11-02 09:00:00 100 153.333333 31.885211 466 2020-11-02 10:00:00 200 153.333333 66.547513 477 2020-11-02 11:00:00 300 153.333333 103.639140 488 2020-11-02 12:00:00 400 153.333333 140.781549 499 2020-11-02 13:00:00 500 153.333333 177.404121 5010 2020-11-03 09:00:00 110 153.333333 169.115345 5111 2020-11-03 10:00:00 120 153.333333 161.658075 5212 2020-11-03 11:00:00 130 153.333333 154.952433 5313 2020-11-03 12:00:00 140 153.333333 148.924717 5414 2020-11-03 13:00:00 150 153.333333 143.510411 55""" 56 57print(df['price'].describe()) 58""" 59count 15.000000 60mean 153.333333 61std 143.510411 62min 10.000000 6325% 45.000000 6450% 120.000000 6575% 175.000000 66max 500.000000 67Name: price, dtype: float64 68"""
投稿2021/10/19 04:33
総合スコア38341
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
以下です。
python
1>>> print(df) 2 日付 時間 price 30 2020-11-01 9:00 10 41 2020-11-01 10:00 20 52 2020-11-01 11:00 30 63 2020-11-01 12:00 40 74 2020-11-01 13:00 50 85 2020-11-02 9:00 100 96 2020-11-02 10:00 200 107 2020-11-02 11:00 300 118 2020-11-02 12:00 400 129 2020-11-02 13:00 500 1310 2020-11-03 9:00 110 1411 2020-11-03 10:00 120 1512 2020-11-03 11:00 130 1613 2020-11-03 12:00 140 1714 2020-11-03 13:00 150 18>>> print(df.groupby('日付')[['price']].std().rename(columns={'price':'標準偏差'}).reset_index()) 19 日付 標準偏差 200 2020-11-01 15.811388 211 2020-11-02 158.113883 222 2020-11-03 15.811388
投稿2021/10/18 14:15
総合スコア24670
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/10/18 14:41
2021/10/18 23:36
2021/10/19 15:08
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。