【问题标题】:Date Difference Between Two Device Failures两个设备故障之间的日期差异
【发布时间】:2019-10-07 09:01:12
【问题描述】:

我正在尝试计算failures 之间的天数。我想知道该系列中的每一天自上次failure 以来经过的天数,其中failure = 1。可能有 1 到 1500 台设备。

例如,我希望我的数据框看起来像这样(请从第二个代码块中的 url 中提取数据。这只是较大数据框的一个简短示例。):

date        device      failure      elapsed    
10/01/2015  S1F0KYCR    1            0           
10/07/2015  S1F0KYCR    1            7           
10/08/2015  S1F0KYCR    0            0           
10/09/2015  S1F0KYCR    0            0           
10/17/2015  S1F0KYCR    1            11          
10/31/2015  S1F0KYCR    0            0           
10/01/2015  S8KLM011    1            0           
10/02/2015  S8KLM011    1            2           
10/07/2015  S8KLM011    0            0
10/09/2015  S8KLM011    0            0
10/11/2015  S8KLM011    0            0
10/21/2015  S8KLM011    1            20 

示例代码:

编辑:请从下面的代码块中提取实际数据。上面的示例数据是一个简短的示例。谢谢。

url = "https://raw.githubusercontent.com/dsdaveh/device-failure-analysis/master/device_failure.csv"

df = pd.read_csv(url, encoding = "ISO-8859-1")

df = df.sort_values(by = ['date', 'device'], ascending = True) #Sort by date and device
df['date'] = pd.to_datetime(df['date'],format='%Y/%m/%d') #format date to datetime

这是我遇到障碍的地方。但是,新列应包含自上次failure 以来的天数,其中failure = 1

test['date'] = 0
for i in test.index[1:]:
    if not test['failure'][i]:
        test['elapsed'][i] = test['elapsed'][i-1] + 1

我也试过

fails = df[df.failure==1]
fails.Dates = trues.index #need this because .diff() won't work on the index..
fails.Elapsed = trues.Dates.diff()

【问题讨论】:

    标签: python pandas date datediff


    【解决方案1】:

    pandas.DataFrame.groupbydiffapply 一起使用:

    import pandas as pd
    import numpy as np
    
    df['date'] = pd.to_datetime(df['date'])
    s = df.groupby(['device', 'failure'])['date'].diff().dt.days.add(1)
    s = s.fillna(0)
    df['elapsed'] = np.where(df['failure'], s, 0)
    

    输出:

             Date    Device  Failure  Elapsed
    0  2015-10-01  S1F0KYCR        1      0.0
    1  2015-10-07  S1F0KYCR        1      7.0
    2  2015-10-08  S1F0KYCR        0      0.0
    3  2015-10-09  S1F0KYCR        0      0.0
    4  2015-10-17  S1F0KYCR        1     11.0
    5  2015-10-31  S1F0KYCR        0      0.0
    6  2015-10-01  S8KLM011        1      0.0
    7  2015-10-02  S8KLM011        1      2.0
    8  2015-10-07  S8KLM011        0      0.0
    9  2015-10-09  S8KLM011        0      0.0
    10 2015-10-11  S8KLM011        0      0.0
    11 2015-10-21  S8KLM011        1     20.0
    

    更新

    发现 OP 中链接的实际数据包含 No 设备有超过两个失败 案例,使最终结果全为零(即没有第二次失败)发生了,因此对于 elapsed 没有什么可计算的)。使用OP的原始sn-p:

    import pandas as pd
    
    url = "http://aws-proserve-data-science.s3.amazonaws.com/device_failure.csv"
    
    df = pd.read_csv(url, encoding = "ISO-8859-1")
    df = df.sort_values(by = ['date', 'device'], ascending = True) 
    df['date'] = pd.to_datetime(df['date'],format='%Y/%m/%d')
    

    查找任何设备是否有超过 1 个故障:

    df.groupby(['device'])['failure'].sum().gt(1).any()
    # False
    

    这实际上证实了df['elapsed'] 中的全零实际上是一个正确的答案:)

    如果您稍微调整一下数据,它确实会产生 elapsed 的结果。

    df.loc[6879, 'device'] = 'S1F0RRB1'
    # Making two occurrence of failure for device S1F0RRB1
    
    s = df.groupby(['device', 'failure'])['date'].diff().dt.days.add(1)
    s = s.fillna(0)
    df['elapsed'] = np.where(df['failure'], s, 0)
    df['elapsed'].value_counts()
    # 0.0    124493
    # 3.0         1
    

    【讨论】:

    • 您可以进一步缩短并转储应用:df.groupby(['Device', 'Failure'])['Date'].diff().dt.days.where(df['Failure'].astype(bool)).add(1).fillna(0, downcast='infer')
    • 这两个建议都会创建一个经过的零列。发生故障时,列中未显示日期差异。它只是一列零。
    • @Starbucks 忘记添加 to_datetime 部分。请再试一次;)
    • @Chris 谢谢克里斯,但我已经在第一个代码块中将其标识为日期时间变量。您是否尝试在第一个 sn-p 中提取数据?对于经过的列,我仍然得到全零。谢谢!
    • elapsed 给了我一堆0s,为什么?
    【解决方案2】:

    这是一种方法

    df['elapsed']=df[df.Failure.astype(bool)].groupby('Device').Date.diff().dt.days.add(1)
    df.elapsed.fillna(0,inplace=True)
    df
    Out[225]: 
             Date    Device  Failure  Elapsed  elapsed
    0  2015-10-01  S1F0KYCR        1        0      0.0
    1  2015-10-07  S1F0KYCR        1        7      7.0
    2  2015-10-08  S1F0KYCR        0        0      0.0
    3  2015-10-09  S1F0KYCR        0        0      0.0
    4  2015-10-17  S1F0KYCR        1       11     11.0
    5  2015-10-31  S1F0KYCR        0        0      0.0
    6  2015-10-01  S8KLM011        1        0      0.0
    7  2015-10-02  S8KLM011        1        2      2.0
    8  2015-10-07  S8KLM011        0        0      0.0
    9  2015-10-09  S8KLM011        0        0      0.0
    10 2015-10-11  S8KLM011        0        0      0.0
    11 2015-10-21  S8KLM011        1       20     20.0
    

    【讨论】:

    • elapsed 给了我一堆0s,为什么?
    • @U9-Forward df['date'] = pd.to_datetime(df['date'],format='%Y/%m/%d')?
    • 是的,我用pd.to_datetime 的东西做到了,又试了一次,结果还是一样
    • 我的旧版本可能有问题
    • @U9-Forward 你的 pandas 版本
    猜你喜欢
    • 2011-10-29
    • 1970-01-01
    • 2014-02-12
    • 2015-09-14
    • 2015-06-21
    • 2020-02-06
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多