0

私が持っているとしましょう

df

                          ts  v
0 2014-11-03 03:39:42.200914  1
1 2014-11-03 03:39:42.500914  2
2 2014-11-03 03:39:43.600914  3
3 2014-11-03 03:39:43.620914  4

vすべての行に、次のような 1 秒のルックバック時間間隔内の sの合計が含まれるように、列 s を追加したい

desired_df
   s                         ts  v
0  1 2014-11-03 03:39:42.200914  1
1  3 2014-11-03 03:39:42.500914  2
2  3 2014-11-03 03:39:43.600914  3
3  7 2014-11-03 03:39:43.620914  4

では、この追加の列を生成するにはどうすればよいsですか?

間隔はオーバーラップする必要がありますが、データフレームのすべての行 (データポイント) に正しいエンドポイントが必要です。つまり、データフレームのすべての行 (データポイント) は、そのサイズの間隔の正しいエンドポイントでなければなりません。

編集: 以下の答えは正しくありませんか?完了

編集:必ずしも1秒だけではなく、14ミリ秒などの一般的な時間間隔でソリューションが機能することを望みます。

どうですか

df['s'] = df.groupby(pd.TimeGrouper(freq='400mS')).transform(numpy.cumsum)

私は得た

                          ts  v  s
0 2014-11-03 03:39:42.200914  1  1
1 2014-11-03 03:39:42.500914  2  2
2 2014-11-03 03:39:43.600914  3  3
3 2014-11-03 03:39:43.620914  4  7

インデックス 1 の行は間違っていませんか? s at 03:39:42.500914 は 2+1=3 である必要があります。2 ではありません。最初の 2 行は 400 ミリ秒以内にあるため、それらを合計する必要があります。なぜそうしないのですか?

編集:試してみると

df['s'] = df.groupby(pd.TimeGrouper(freq='340mS')).transform(numpy.cumsum)

時間間隔が短くても、実際にはそのグループ化を実行します。

                            v  s
ts                              
2014-11-03 03:39:42.200914  1  1
2014-11-03 03:39:42.500914  2  3
2014-11-03 03:39:43.600914  3  3
2014-11-03 03:39:43.620914  4  7

では、TimeGrouper が配置する区切り記号 (区切り記号) はどこにあるのでしょうか? 間隔の右端点を、見ている行 (s が対応する行) と一致させたい

4

1 に答える 1

3

ts次のように、インデックスとして設定してから2番目に設定し、新しい列sgroupbyとして変換してから適用します。cumsum()reset_index

df
                          ts  v
0 2014-11-03 03:39:42.200914  1
1 2014-11-03 03:39:42.500914  2
2 2014-11-03 03:39:43.600914  3
3 2014-11-03 03:39:43.620914  4

df = df.set_index('ts')

df['s'] = df.groupby(lambda x: x.second).transform(cumsum)
df = df.reset_index()
df

                          ts  v  s
0 2014-11-03 03:39:42.200914  1  1
1 2014-11-03 03:39:42.500914  2  3
2 2014-11-03 03:39:43.600914  3  3
3 2014-11-03 03:39:43.620914  4  7

列を並べ替えたい場合があります。

df = df[['s','ts','v']]
df
   s                         ts  v
0  1 2014-11-03 03:39:42.200914  1
1  3 2014-11-03 03:39:42.500914  2
2  3 2014-11-03 03:39:43.600914  3
3  7 2014-11-03 03:39:43.620914  4

更新しました

ジェネリックメソッドが必要であるというOPの更新として、pd.TimeGrouper使用できます:

別の更新 (完全な手順が提供されます)

df = pd.DataFrame([['2014-11-03 03:39:42.200914',1],['2014-11-03 03:39:42.500914', 2],['2014-11-03 03:39:43.600914',3],['2014-11-03 03:39:43.620914', 4]], columns=['ts','v'], dtype=object)

# you will get type error if you haven't converted your string to datetime 
df['ts'] = [pd.to_datetime(d) for d in df['ts']]

df = df.set_index('ts')

この行を参照してください

# from the doc we need to add closed='left' to include the first nbin count
df['s'] = df.groupby(pd.TimeGrouper(freq='340mS', closed='left')).transform(cumsum)

# reset the index
df = df.reset_index()

# reorder the columns
df = df[['s', 'ts', 'v']]

df
   s                         ts  v
0  1 2014-11-03 03:39:42.200914  1
1  3 2014-11-03 03:39:42.500914  2
2  3 2014-11-03 03:39:43.600914  3
3  7 2014-11-03 03:39:43.620914  4

ただし、「400mS」では、まだ望ましい結果が得られていないことに同意しました。

于 2014-11-03T16:46:52.817 に答える