Разница в дате между двумя сбоями устройства - PullRequest
7 голосов
/ 21 мая 2019

Я пытаюсь подсчитать количество дней между 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()

Ответы [ 2 ]

5 голосов
/ 21 мая 2019

Использование pandas.DataFrame.groupby с diff и apply:

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:

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'] на самом деле правильный ответ:)

Если вы немного подправите данные, это даст истек , как и ожидалось.

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
0 голосов
/ 21 мая 2019

Вот один из способов

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
...