我有一些时间序列数据,我希望按类别分开,并在二进制值== 1时进一步分开。我想计算二进制值== 1时每天所经过的时间。
以下是原始数据样本:
category binary
utctime
2014-10-23 13:15:08 a 0
2014-10-24 16:09:13 b 0
2014-10-24 18:56:01 a 1
2014-10-24 21:42:42 a 1
2014-10-25 00:29:22 a 0
2014-10-25 03:16:02 c 1
2014-10-25 06:02:43 c 1
2014-10-25 08:49:23 c 0
2014-10-25 11:36:03 c 1
2014-10-25 14:22:43 c 1
2014-10-25 17:09:24 d 0
2014-10-25 19:56:05 b 0
2014-10-25 22:42:45 b 0
2014-10-26 01:29:26 e 0
2014-10-26 04:16:15 d 0
2014-10-26 07:02:56 e 1
2014-10-26 09:49:36 e 1
2014-10-26 12:36:16 e 0
2014-10-26 15:22:57 e 0
2014-10-26 18:09:46 d 0
2014-10-26 20:56:26 b 0
2014-10-26 23:43:07 e 0
我开始过滤二进制列,然后按类别分组,但我丢失了日期索引。如果我按index.date(或pd.date_grouper)分组,我不知道如何分组到单独的类别。
感觉数据可能处于特别无益的状态,但我不知道如何让它变得更好 - 我尝试了一个以类别为列的数据透视表,但由于utctimes是类别所特有的,没有工作。我应该把utctime从索引中删除吗?
所需的输出类似于以下内容:
category a
date total time binary == 1
2014-10-23 10 minutes
2014-10-24 5 minutes
category b
date total time binary == 1
2014-10-23 1 minutes
2014-10-24 15 minutes
答案 0 :(得分:2)
要按类别和索引日期分组,您可以使用
date = df2.index.date
grouped = df2.groupby(['category', date])
请注意,groupby可以接受包含字符串和数组的列表。该
string指的是列名,而数组则充当虚拟的代理
柱。 date
不是df2
的列,但您可以按其分组。很酷,嗯?
要查找每个组中的总分钟数,您可以使用lambda函数(例如
)进行聚合lambda x: (x.index[-1]-x.index[0])/pd.Timedelta(1, 'm')
(x.index[-1]-x.index[0])
计算每个组中第一个和最后一个时间戳之间的差异。请注意,这假定索引按排序顺序排列。
差异(x.index[-1]-x.index[0])
会返回pd.Timedelta
。
除以pd.Timedelta(1, 'm')
将返回总分钟数。
请注意,使用g.last()-g.first()
的{{3}}对于大型DataFrame可能要快得多,因为它在一个向量化操作中计算所有Timedeltas,而不是为每个Timedelta计算一个lambda函数调用行。
import numpy as np
import pandas as pd
df = pd.DataFrame(
[['2014-10-23 13:15:08', 'a', 999.9, 0],
['2014-10-24 16:09:13', 'b', 24.1, 0],
['2014-10-24 18:56:01', 'a', 23.3, 1],
['2014-10-24 21:42:42', 'a', 23.0, 1],
['2014-10-25 00:29:22', 'a', 22.7, 0],
['2014-10-25 03:16:02', 'c', 23.1, 1],
['2014-10-25 06:02:43', 'c', 22.8, 1],
['2014-10-25 08:49:23', 'c', 23.7, 1],
['2014-10-25 11:36:03', 'c', 24.8, 0],
['2014-10-25 14:22:43', 'c', 25.7, 0],
['2014-10-25 17:09:24', 'd', 24.9, 0],
['2014-10-25 19:56:05', 'b', 24.6, 0],
['2014-10-25 22:42:45', 'b', 24.2, 0],
['2014-10-26 01:29:26', 'e', 22.7, 0],
['2014-10-26 04:16:15', 'd', 23.6, 0],
['2014-10-26 07:02:56', 'e', 22.4, 1],
['2014-10-26 09:49:36', 'e', 22.7, 1],
['2014-10-26 12:36:16', 'e', 22.2, 0],
['2014-10-26 15:22:57', 'e', 23.1, 0],
['2014-10-26 18:09:46', 'd', 23.8, 0],
['2014-10-26 20:56:26', 'b', 23.8, 0],
['2014-10-26 23:43:07', 'e', 22.7, 0]],
columns=['utctime', 'category', 'temp', 'binary'])
df = df.set_index('utctime')
df.index = pd.DatetimeIndex(df.index)
df2 = df.loc[df['binary']==1]
date = df2.index.date
grouped = df2.groupby(['category', date])
result = grouped['binary'].agg(
lambda x: (x.index[-1]-x.index[0])/pd.Timedelta(1, 'm'))
print(result)
产量
category
a 2014-10-24 166.683333
c 2014-10-25 333.350000
e 2014-10-26 166.666667
Name: binary, dtype: float64
答案 1 :(得分:2)
使用@unutbu数据&设置
添加一个我们想要差异的额外列
app.controller('navigationCtrl', function ($scope, $stateParams, $location, $state) {
稍微更通用的分组方式
In [31]: df2['ts'] = df2.index
In [32]: df2
Out[32]:
category temp binary ts
2014-10-24 18:56:01 a 23.3 1 2014-10-24 18:56:01
2014-10-24 21:42:42 a 23.0 1 2014-10-24 21:42:42
2014-10-25 03:16:02 c 23.1 1 2014-10-25 03:16:02
2014-10-25 06:02:43 c 22.8 1 2014-10-25 06:02:43
2014-10-25 08:49:23 c 23.7 1 2014-10-25 08:49:23
2014-10-26 07:02:56 e 22.4 1 2014-10-26 07:02:56
2014-10-26 09:49:36 e 22.7 1 2014-10-26 09:49:36
虽然是YMMV,但性能会更高。
In [33]: g = df2.groupby(['category',pd.Grouper(freq='D',level=0)])