pandas按n秒分组并应用任意滚动函数

8

我有一些加速度计读数的csv数据,格式如下(实际数据采样率更高):

2013-09-28 17:36:50.322120,  0.152695, -0.545074, -0.852997
2013-09-28 17:36:50.622988,  0.141800, -0.554947, -0.867935
2013-09-28 17:36:51.923802,  0.132431, -0.547089, -0.879333
2013-09-28 17:36:52.124641,  0.124329, -0.530243, -0.887741
2013-09-28 17:36:52.425341,  0.122269, -0.519669, -0.900269
2013-09-28 17:36:52.926202,  0.122879, -0.502151, -0.902023
....
....
....
....
2013-09-28 17:49:14.440343,  0.005447, -0.623016, -0.773529
2013-09-28 17:49:14.557806,  0.009048, -0.623093, -0.790909
2013-09-28 17:49:14.758442,  0.007217, -0.617386, -0.815796

我使用pandas加载它们

import pandas as pd
accDF=pd.read_csv(accFileName,header=0, sep=',') 
accDF.columns=['time','x','y','z']
accDF=accDF.set_index(['time'])

加速度计数据不是均匀采样的,我想按照每10、20或30秒分组数据,并对数据组应用自定义函数。
如果数据是均匀采样的,那么应用滚动函数就很容易。但由于数据不是这样的,我想使用时间戳间隔来应用分组功能。使用1秒的间隔很容易实现:
accDF_win=accDF.groupby(accDF.index.second).apply... etc

然而,我无法想出如何按任意秒数分组,然后对其应用函数。

使用TimeGrouper,我可以执行以下操作:

accDF_win=accDF.groupby(pd.TimeGrouper(freq='3Min'))

需要对任意数量的分钟进行操作,但是TimeGrouper似乎没有“秒”分辨率。

提前感谢您的帮助。

2个回答

4

首先,您需要将时间列转换为Python时间对象(如果尚未转换)。

>>> import pandas as pd
>>> from dateutil import parser
>>> df=pd.read_csv("test.csv",header=None,date_parser=True)
#convert to datetime index, f.e. with dateutil
>>> df=df.set_index(df[0].map(parser.parse)

接下来使用pd.TimeGrouper操作如下:

>>> df[3].groupby(pd.TimeGrouper('10S')).head()
2013-09-28 17:36:40  2013-09-28 17:36:40.322120   -0.852997
                     2013-09-28 17:36:41.622988   -0.867935
                     2013-09-28 17:36:42.923802   -0.879333
                     2013-09-28 17:36:43.124641   -0.887741
                     2013-09-28 17:36:45.425341   -0.900269
2013-09-28 17:36:50  2013-09-28 17:36:52.926202   -0.902023
                     2013-09-28 17:36:53.322120   -0.852997
                     2013-09-28 17:36:53.622988   -0.867935
                     2013-09-28 17:36:54.923802   -0.879333
                     2013-09-28 17:36:54.124641   -0.887741
2013-09-28 17:49:50  2013-09-28 17:49:56.440343   -0.773529
                     2013-09-28 17:49:56.557806   -0.790909
                     2013-09-28 17:49:57.758442   -0.815796

或者您可以查看重新采样函数这里。也许您可以应用自定义重新采样函数,而不是使用groupby方法。
df[3].resample("10S",how=lambda x: Whateveryouwanttodo)

如果没有任何函数,它会填充NaN:

>>> df[3].resample("10S")
0
2013-09-28 17:36:40   -0.877655
2013-09-28 17:36:50   -0.884617
2013-09-28 17:37:00         NaN
2013-09-28 17:37:10         NaN
2013-09-28 17:37:20         NaN
2013-09-28 17:37:30         NaN
2013-09-28 17:37:40         NaN

1
请注意,在pandas 0.21中,TimeGrouper已被弃用,建议使用带有参数freqGrouper - normanius

2
我认为你不需要使用 TimeGrouper。支持按秒重新采样。你并不是第一个尝试使用“S”表示秒(所以也许 pandas 应该支持它?);正确的字符串应该是“s”。
df = pd.read_csv(filename, parse_dates=True, sep=',', index_col=0, header=None)
df.columns = ['x', 'y', 'z']
df.resample('10s', how=f)  # where f is your function

编辑:实际上,在我的版本(即将发布的0.13版本)中,我发现“10S”也可以使用。也许你的整个问题在于没有解析日期。

实际上,他甚至没有尝试过“Sec” ;) - dorvak
看起来这个在某个时候改变了;也许他使用的是旧版本的pandas,其中S和Sec不好用。 - Dan Allan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接