改题目来源于力扣:
1661. 每台机器的进程平均运行时间 - 力扣(LeetCode)
题目要求:
表: Activity
+----------------+---------+ | Column Name | Type | +----------------+---------+ | machine_id | int | | process_id | int | | activity_type | enum | | timestamp | float | +----------------+---------+ 该表展示了一家工厂网站的用户活动。 (machine_id, process_id, activity_type) 是当前表的主键(具有唯一值的列的组合)。 machine_id 是一台机器的ID号。 process_id 是运行在各机器上的进程ID号。 activity_type 是枚举类型 ('start', 'end')。 timestamp 是浮点类型,代表当前时间(以秒为单位)。 'start' 代表该进程在这台机器上的开始运行时间戳 , 'end' 代表该进程在这台机器上的终止运行时间戳。 同一台机器,同一个进程都有一对开始时间戳和结束时间戳,而且开始时间戳永远在结束时间戳前面。
现在有一个工厂网站由几台机器运行,每台机器上运行着 相同数量的进程 。编写解决方案,计算每台机器各自完成一个进程任务的平均耗时。
完成一个进程任务的时间指进程的'end' 时间戳
减去 'start' 时间戳
。平均耗时通过计算每台机器上所有进程任务的总耗费时间除以机器上的总进程数量获得。
结果表必须包含machine_id(机器ID)
和对应的 average time(平均耗时) 别名 processing_time
,且四舍五入保留3位小数。
以 任意顺序 返回表。
具体参考例子如下。
示例 1:
输入: Activity table: +------------+------------+---------------+-----------+ | machine_id | process_id | activity_type | timestamp | +------------+------------+---------------+-----------+ | 0 | 0 | start | 0.712 | | 0 | 0 | end | 1.520 | | 0 | 1 | start | 3.140 | | 0 | 1 | end | 4.120 | | 1 | 0 | start | 0.550 | | 1 | 0 | end | 1.550 | | 1 | 1 | start | 0.430 | | 1 | 1 | end | 1.420 | | 2 | 0 | start | 4.100 | | 2 | 0 | end | 4.512 | | 2 | 1 | start | 2.500 | | 2 | 1 | end | 5.000 | +------------+------------+---------------+-----------+ 输出: +------------+-----------------+ | machine_id | processing_time | +------------+-----------------+ | 0 | 0.894 | | 1 | 0.995 | | 2 | 1.456 | +------------+-----------------+ 解释: 一共有3台机器,每台机器运行着两个进程. 机器 0 的平均耗时: ((1.520 - 0.712) + (4.120 - 3.140)) / 2 = 0.894 机器 1 的平均耗时: ((1.550 - 0.550) + (1.420 - 0.430)) / 2 = 0.995 机器 2 的平均耗时: ((4.512 - 4.100) + (5.000 - 2.500)) / 2 = 1.456
思路流程:
简单来说就是machine_id列表示每个机器的编号,process_id表示每个工作的编号,现在我们要查询出每个机器的的每个工作的时间长度的平均。
首先。表中的数据没有顺序可言,必须要对它就像排序,原先排序machine_id列,使得每个机器区分开来,其次排序process_id,将每个工作区分开来,最后排序timestamp,对后续的diff()函数遍历打下基础,区分开开始和结束的时间。
然后,按照machine_id列和process_id列进行分组,使得每个机器和每个机器的每个工作区分开来。利用diff()函数(diff函数,计算每个元素与组中另一个元素的差,默认前一列的元素)
最后,进行聚合。即求取分组时间的平均值。
可见,这是一个稍微复杂的分组聚合问题。
代码实现:
import pandas as pd
def get_average_time(activity: pd.DataFrame) -> pd.DataFrame:
activity['processing_time'] = activity.sort_values(['machine_id','process_id','timestamp']).groupby(['machine_id','process_id'])['timestamp'].diff()
return activity.dropna().groupby('machine_id',as_index=False)['processing_time'].mean().round(3)