- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用
目录
一,原题力扣链接
二,题干
表:
Failed
+--------------+---------+ | Column Name | Type | +--------------+---------+ | fail_date | date | +--------------+---------+ 该表主键为 fail_date (具有唯一值的列)。 该表包含失败任务的天数.表:
Succeeded
+--------------+---------+ | Column Name | Type | +--------------+---------+ | success_date | date | +--------------+---------+ 该表主键为 success_date (具有唯一值的列)。 该表包含成功任务的天数.系统 每天 运行一个任务。每个任务都独立于先前的任务。任务的状态可以是失败或是成功。
编写解决方案找出 2019-01-01 到 2019-12-31 期间任务连续同状态
period_state
的起止日期(start_date
和end_date
)。即如果任务失败了,就是失败状态的起止日期,如果任务成功了,就是成功状态的起止日期。最后结果按照起始日期
start_date
排序返回结果样例如下所示:
示例 1:
输入: Failed table: +-------------------+ | fail_date | +-------------------+ | 2018-12-28 | | 2018-12-29 | | 2019-01-04 | | 2019-01-05 | +-------------------+ Succeeded table: +-------------------+ | success_date | +-------------------+ | 2018-12-30 | | 2018-12-31 | | 2019-01-01 | | 2019-01-02 | | 2019-01-03 | | 2019-01-06 | +-------------------+ 输出: +--------------+--------------+--------------+ | period_state | start_date | end_date | +--------------+--------------+--------------+ | succeeded | 2019-01-01 | 2019-01-03 | | failed | 2019-01-04 | 2019-01-05 | | succeeded | 2019-01-06 | 2019-01-06 | +--------------+--------------+--------------+ 解释: 结果忽略了 2018 年的记录,因为我们只关心从 2019-01-01 到 2019-12-31 的记录 从 2019-01-01 到 2019-01-03 所有任务成功,系统状态为 "succeeded"。 从 2019-01-04 到 2019-01-05 所有任务失败,系统状态为 "failed"。 从 2019-01-06 到 2019-01-06 所有任务成功,系统状态为 "succeeded"。
三,建表语句
import pandas as pd
data = [['2018-12-28'], ['2018-12-29'], ['2019-01-04'], ['2019-01-05']]
failed = pd.DataFrame(data, columns=['fail_date']).astype({'fail_date':'datetime64[ns]'})
data = [['2018-12-30'], ['2018-12-31'], ['2019-01-01'], ['2019-01-02'], ['2019-01-03'], ['2019-01-06']]
succeeded = pd.DataFrame(data, columns=['success_date']).astype({'success_date':'datetime64[ns]'})
四,分析
题解:
表一:任务执行失败表:
字段:任务执行失败的时间
表二:任务执行成功表
字段:任务执行成功的时间
--------------处理任务失败的表---------------------
第一步:过滤 非2019年的行
第二步:排序
第三步,类似sql中的row_number 生成一个排序列 pandas中可以用索引巧妙生成
第四步,取 差值 连续问题必要的一步
第五步:取最大值和最小值
第六步:创建一个新df对象 拼接上三列
------------任务执行成功的表 逻辑同上-----------------
详情见代码 这里展示任务执行成功的表 最后一步的效果
最后一步 纵向合并两个表 并且排序
五,Pandas解答
import pandas as pd
def report_contiguous_dates(failed: pd.DataFrame, succeeded: pd.DataFrame) -> pd.DataFrame:
''' 先处理failed 在处理 succeeded 最后拼接一下 然后在排序 '''
#第一步过滤
df = failed[failed['fail_date'].dt.year==2019]
#第二步:排序
df = df.sort_values('fail_date')
#第三步:生成类似sql中 row_number的效果 列
df['rn']=df.reset_index().index+1
#第四步 取差值
df['diff'] = df['fail_date'] - pd.to_timedelta(df['rn'], unit='D')
#第五步 分组 取max和min的值
df_max= df.groupby('diff')['fail_date'].max().reset_index()['fail_date']
df_min = df.groupby('diff')['fail_date'].min().reset_index()['fail_date']
#第六步 创建一个df对象 然后分别指定对应的列
df_f = pd.DataFrame()
df_f['period_state'] = ['failed']*len(df_max)
df_f['start_date']= df_min
df_f['end_date'] = df_max
'''--------------------开始处理 succeeded----------------------'''
#第一步过滤
df1 = succeeded[succeeded['success_date'].dt.year==2019]
#第二步:排序
df1 = df1.sort_values('success_date')
# #第三步:生成类似sql中 row_number的效果 列
df1['rn']=df1.reset_index().index+1
# #第四步 取差值
df1['diff'] = df1['success_date'] - pd.to_timedelta(df1['rn'], unit='D')
# #第五步 分组 取max和min的值
df_max1 = df1.groupby('diff')['success_date'].max().reset_index()['success_date']
df_min1 = df1.groupby('diff')['success_date'].min().reset_index()['success_date']
#第六步 创建一个df对象 然后分别指定对应的列
df_f1 = pd.DataFrame()
df_f1['period_state'] = ['succeeded']*len(df_min1)
df_f1['start_date']= df_min1
df_f1['end_date'] = df_max1
'''----------------------纵向合并两个表 并且排序------------------------------'''
res = pd.concat([df_f,df_f1])
res = res.sort_values('start_date')
return res
六,验证
七,知识点总结
- Pandas中条件过滤的运用
- Pandas时间类型的取年运用 API: dt.year
- Pandas中排序的运用 API: sort_values
- Pandas中类似sql中row_number的效果实现 巧用索引生成一个新列
- Pandas中时间类型取差值的函数的实现 API:to_timedelta
- Pandas中分组聚合取最大值的运用 API:groupby....max
- Pandas中分组聚合取最小值的运用 API:groupby...min
- Pandas中创建df对象的运用 API: pd.DataFrame
- Pandas中获取行行数的运用 API:len(列)
- Pandas中纵向合并表的运用 API:concat
- Pandas中新增列的运用
- 经典题目:获取连续执行成功/失败的任务
- 连续问题 思路用差值处理~
- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用