假设我有
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
我想追加一个列s,这样在每一行中,它包含1秒回顾时间间隔内v
的总和,例如
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
?
Noe,间隔应该重叠,但它们必须在数据帧的每一行(datapoint)都有正确的端点,即我的数据帧中的每一行(datapoint)必须是该大小的间隔的右端点。
编辑:下面的回答是不对的?完整的
编辑:我希望该解决方案适用于通用时间间隔,例如14ms,不一定只持续1秒。
怎么样
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是不是错了?在03:39:42.500914应该是2 + 1 = 3。不是2,因为前2行都在400ms之内,所以应该将它们加在一起。为什么不这样做?
编辑:当我尝试
时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对应的行)重合
答案 0 :(得分:3)
将ts
设置为索引,然后设置groupby
秒,然后使用cumsum()
转换为新列 s ,然后应用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'我同意我们仍然没有得到愿望的结果。