17,Python数分之Pandas训练,1225. 报告系统状态的连续日期

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用

目录

一,原题力扣链接

二,题干

三,建表语句

四,分析

五,Pandas解答

六,验证

七,知识点总结


一,原题力扣链接

. - 力扣(LeetCode)

二,题干

表: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中新增列的运用
  • 经典题目:获取连续执行成功/失败的任务
  • 连续问题 思路用差值处理~

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值