2017-04-27 10 views
4

私はdatetime型の列とfloat型の列を持つデータフレームを持っています。パンダ:datetimeの複合条件

 
        date value 
0  2010-01-01 01:23:00 21.2 
1  2010-01-02 01:33:00 63.4 
2  2010-01-03 06:02:00 80.6 
3  2010-01-04 06:05:00 50.1 
4  2010-01-05 06:20:00 346.5 
5  2010-01-06 07:44:00 111.8 
6  2010-01-07 08:00:00 113.1 
7  2010-01-08 08:22:00 10.6 
8  2010-01-09 09:00:00 287.2 
9  2010-01-10 09:14:00 1652.6 

新しい列を作成して、現在の反復行時刻の1時間前の平均値を記録したいとします。

[UPDATE]例

現在の反復が4 2010-01-05 06:20:00 346.5ある場合、私は(50.1 + 80.6)/2(範囲2010-01-05 05:20:00~2010-01-05 06:20:00の値を平均計算)を計算する必要があります。私は次のコードのように、この問題を解決するためにiterrows()を使用

 
        date value before_1hr_mean 
4  2010-01-05 06:20:00 346.5 65.35 

。しかし、この方法は本当に遅く、機能iterrows()は通常パンダで推奨されていないと、この行のようになります

[UPDATE]

df['before_1hr_mean'] = np.nan 
for index, row in df.iterrows(): 
    df.loc[index, 'before_1hr_mean'] = df[(df['date'] < row['date']) & \ 
     (df['date'] >= row['date'] - pd.Timedelta(hours=1))]['value'].mean() 

このような状況に対処するためのより良い方法はありますか?

+0

あなたの例が数日ごとに増えていることを理解していますか?結果が元のデータと同じであることを意味します。この例では、1行の平均をとっています。 – piRSquared

+0

また、 'df ['date'] <= row ['date']'は現在の行の値を平均値に含めることを意味します。しかし、あなたの計算例では、現在の行の値を除外します。これはまた、最初の行の計算がnullになることを意味します。 – piRSquared

+0

私の間違ったコードを申し訳ありません。私は等号を間違った位置に置いた。あなたのコードから多くのことを学んでください。この場合、nullまたはNanは大丈夫です。 – zue

答えて

3

私はあなたのデータをすべて同じ日に変更する自由を取った。私があなたの質問を理解できる唯一の方法です。

df.join(
    df.set_index('date').value.rolling('H').mean().rename('before_1hr_mean'), 
    on='date' 
) 

       date value before_1hr_mean 
0 2010-01-01 01:23:00 21.2  21.200000 
1 2010-01-01 01:33:00 63.4  42.300000 
2 2010-01-01 06:02:00 80.6  80.600000 
3 2010-01-01 06:05:00 50.1  65.350000 
4 2010-01-01 06:20:00 346.5  159.066667 
5 2010-01-01 07:44:00 111.8  111.800000 
6 2010-01-01 08:00:00 113.1  112.450000 
7 2010-01-01 08:22:00 10.6  78.500000 
8 2010-01-01 09:00:00 287.2  148.900000 
9 2010-01-01 09:14:00 1652.6  650.133333 

あなたは現在の行を除外したい場合は、ローリング時間の合計と数を追跡し、平均電流値を調整した後で何をバックアウトする必要があります。

s = df.set_index('date') 
sagg = s.rolling('H').agg(['sum', 'count']).value.rename(columns=str.title) 
agged = df.join(sagg, on='date') 
agged 

       date value  Sum Count 
0 2010-01-01 01:23:00 21.2 21.2 1.0 
1 2010-01-01 01:33:00 63.4 84.6 2.0 
2 2010-01-01 06:02:00 80.6 80.6 1.0 
3 2010-01-01 06:05:00 50.1 130.7 2.0 
4 2010-01-01 06:20:00 346.5 477.2 3.0 
5 2010-01-01 07:44:00 111.8 111.8 1.0 
6 2010-01-01 08:00:00 113.1 224.9 2.0 
7 2010-01-01 08:22:00 10.6 235.5 3.0 
8 2010-01-01 09:00:00 287.2 297.8 2.0 
9 2010-01-01 09:14:00 1652.6 1950.4 3.0 

その後、いくつかの計算を行う前のデータの価値は時間にわたり計算することがないときはnullを取得し、新しい列

df.assign(before_1hr_mean=agged.eval('(Sum - value)/(Count - 1)')) 

       date value before_1hr_mean 
0 2010-01-01 01:23:00 21.2    NaN 
1 2010-01-01 01:33:00 63.4   21.20 
2 2010-01-01 06:02:00 80.6    NaN 
3 2010-01-01 06:05:00 50.1   80.60 
4 2010-01-01 06:20:00 346.5   65.35 
5 2010-01-01 07:44:00 111.8    NaN 
6 2010-01-01 08:00:00 113.1   111.80 
7 2010-01-01 08:22:00 10.6   112.45 
8 2010-01-01 09:00:00 287.2   10.60 
9 2010-01-01 09:14:00 1652.6   148.90 

お知らせを割り当てます。

+1

OPが何を求めているのか分かっていませんが、「before_1hr_mean」の列が値の列とまったく同じであることはちょっと変わっていませんか? – DSM

+0

それは奇妙です...私はそれに気付かなかった。さて、これでワームの缶があいまいになります。 OPのほうが良い例が必要ですし、コードが何をしているのか解読できます。ところで、彼らのコードは同じことを生み出します。 – piRSquared

+0

ええ、私はOPが「1時間前」について話しているが、なぜ各行が異なる_date_であるかを指定する必要があると思う。 – DSM