Замените пустое значение даты-времени другим значением даты-времени из того же фрейма данных на основе некоторого условия

#python #pandas #dataframe #datetime

Вопрос:

У меня есть фрейм данных:

                   login   Status               start
0   2021-05-28 09:29:35 Resolved                 NaT
1   2021-05-28 11:46:11   Closed                 NaT
2   2021-05-29 15:59:16      WIP                 NaT
3   2021-05-30 10:43:57   Closed 2021-05-31 12:53:57
4   2021-06-27 17:53:29 Resolved                 NaT
 

Я хочу заполнить start значение login значением, если начато NULL , а статус либо разрешен, либо закрыт.
Ожидаемый кадр данных:

                   login   Status               start
0   2021-05-28 09:29:35 Resolved 2021-05-28 09:29:35
1   2021-05-28 11:46:11   Closed 2021-05-28 11:46:11
2   2021-05-29 15:59:16      WIP                 NaT
3   2021-05-30 10:43:57   Closed 2021-05-31 12:53:57
4   2021-06-27 17:53:29 Resolved 2021-06-27 17:53:29
 

я не могу поставить условие для Null начальных значений

Я попытался создать функцию :

 def fun(row):       
    if row.start.isna() and (row['Status'] == 'Resolved') or (row['Status' == 'Closed']):
        return row['start']
    else:
        return row['login']
 

а затем использовать apply для запуска функции:

 df['start'] = df.apply(fun, axis=1)
 

Но я получаю ошибку :

 AttributeError: 'Timestamp' object has no attribute 'isna'
 

Как мы можем получить вышеуказанный результат

ТИА

Комментарии:

1. Попробуйте использовать .isnull() , а не .isna() ?

2. Та же ошибка > Ошибка атрибута: объект «Отметка времени» не имеет атрибута «isnull»

Ответ №1:

Мы можем fill ввести NaT значения start после маскировки значений в login тех случаях, когда соответствующее Status значение не является одним из Closed, Resolved

 m = df['Status'].isin(['Resolved', 'Closed'])
df['start'] = df['start'].fillna(df['login'].mask(~m))
 

   login                Status   start
0 2021-05-28 09:29:35  Resolved 2021-05-28 09:29:35
1 2021-05-28 11:46:11    Closed 2021-05-28 11:46:11
2 2021-05-29 15:59:16       WIP                 NaT
3 2021-05-30 10:43:57    Closed 2021-05-31 12:53:57
4 2021-06-27 17:53:29  Resolved 2021-06-27 17:53:29
 

Ответ №2:

Просто fillna() с .loc[]

 df = pd.read_csv(io.StringIO("""                  login   Status               start
0   2021-05-28 09:29:35  Resolved                 NaT
1   2021-05-28 11:46:11   Closed                 NaT
2   2021-05-29 15:59:16      WIP                 NaT
3   2021-05-30 10:43:57   Closed  2021-05-31 12:53:57
4   2021-06-27 17:53:29  Resolved                 NaT"""), sep="ss ", engine="python")
df["login"] = pd.to_datetime(df["login"])
df["start"] = pd.to_datetime(df["start"])

df.loc[~df["Status"].eq("WIP"),"start"] = df.loc[~df["Status"].eq("WIP"),"start"].fillna(df["login"])

df
 
войти Статус начало
0 2021-05-28 09:29:35 Решенный 2021-05-28 09:29:35
1 2021-05-28 11:46:11 Закрытый 2021-05-28 11:46:11
2 2021-05-29 15:59:16 НЗП натуральный
3 2021-05-30 10:43:57 Закрытый 2021-05-31 12:53:57
4 2021-06-27 17:53:29 Решенный 2021-06-27 17:53:29