我的数据框中有大约500,000个条目,我想对这些数据应用某种平滑,以便显着减少条目数量。
这是一个示例数据框df
:
EVENT GRADE SERVICE_TIME QUEUE_TIME HOLD_TIME
AAA 3 170 20 12
AAA 4 165 15 10
AAA 3 172 24 12
AAA 3 105 5 10
BBB 5 40 10 10
BBB 5 60 10 8
目标是降低SERVICE_TIME
,QUEUE_TIME
和HOLD_TIME
的粒度。
为此,我想按EVENT
和GRADE
对参赛作品进行分组,并为60秒的切片窗口估算SERVICE_TIME
的平均值(即[0; 60] ,[61; 120],[121; 180],[181; 240],依此类推,直至SERVICE_TIME
的最大值。切片窗口的大小可以灵活地从60变为任何其他值,这一点很重要。
因此,切片应该应用于SERVICE_TIME
,而其他列QUEUE_TIME
和QUEUE_TIME
应该相应地进行平均。
示例结果:
EVENT GRADE SERVICE_TIME QUEUE_TIME HOLD_TIME
AAA 3 171 22 12
AAA 3 105 5 10
AAA 4 165 15 10
BBB 5 50 10 9
因此,合并了SERVICE_TIME
,170和172这两个值,因为它们都属于切片窗口[121; 180]。因此,我计算了平均值171
,然后我只计算QUEUE_TIME
和HOLD_TIME
的相应值。
我该怎么做切片?
如果我不得不计算一个平均值(没有切片),那么我会这样做。
result = df.groupby(['EVENT','GRADE']).agg({'SERVICE_TIME': 'mean',
'QUEUE_TIME': 'mean',
'HOLD_TIME': 'mean'}).reset_index()
答案 0 :(得分:2)
你基本上有正确的想法,除了['EVENT','GRADE']
而不是仅按SERVICE_GROUP
进行分组,你还想要df['SERVICE_GROUP'] = (df['SERVICE_TIME']-1)//60
分组:
import numpy as np
import pandas as pd
df = pd.DataFrame({'EVENT': ['AAA', 'AAA', 'AAA', 'AAA', 'BBB', 'BBB'],
'GRADE': [3, 4, 3, 3, 5, 5],
'HOLD_TIME': [12, 10, 12, 10, 10, 8],
'QUEUE_TIME': [20, 15, 24, 5, 10, 10],
'SERVICE_TIME': [170, 165, 172, 105, 40, 60]})
df['SERVICE_GROUP'] = (df['SERVICE_TIME']-1)//60
result = (df.groupby(['EVENT','GRADE', 'SERVICE_GROUP'])
.agg({'SERVICE_TIME': 'mean',
'QUEUE_TIME': 'mean',
'HOLD_TIME': 'mean'}).reset_index())
result = result.drop('SERVICE_GROUP', axis=1)
print(result)
EVENT GRADE QUEUE_TIME SERVICE_TIME HOLD_TIME
0 AAA 3 5 105 10
1 AAA 3 22 171 12
2 AAA 4 15 165 10
3 BBB 5 10 50 9
打印
(df['SERVICE_TIME']-1)//60
SERVICE_GROUP
中的-1代表SERVICE_TIMES
0的60分。
否则,df['SERVICE_GROUP'] = (df['SERVICE_TIME']-1)//60
40和60将不会组合在一起。
因此SERVICE_TIME
导致了
(1, 60], (60, 120], (120, 180], ...
组为半开区间
list
答案 1 :(得分:1)
您可以生成一个基于窗口划分的新列(此处为'SERVICE_TIME_GROUP')。然后使用这个新专栏进行分组。分组后你可以放弃它。
WINDOW = 60
df['SERVICE_TIME_GROUP'] = df['SERVICE_TIME'].apply(lambda x : 1 if x==0 else math.ceil(x/(WINDOW*1.0));
result = df.groupby(['EVENT','GRADE','SERVICE_TIME_GROUP']).agg({'SERVICE_TIME': 'mean',
'QUEUE_TIME': 'mean',
'HOLD_TIME': 'mean'}).reset_index()
result = result.drop('SERVICE_TIME_GROUP', 1)
对于[0; 60],[61; 120],[121; 180],[181; 240],ceil函数将起作用。一个特殊情况是0,需要单独处理。否则只需按窗口大小划分并将其细化,即可得到一组。
0 => 1
1-60 => 1
61-120 => 2
121-180 => 3
...