#python #dataframe #if-statement #filter #boolean
Вопрос:
У меня есть фрейм данных, который выглядит так
продукт | Продолжительность |
---|---|
замена шин | 01:16:51 |
замена масла | 05:06:00 |
замена шин | 02:03:04 |
замена масла | 06:23:14 |
замена масла | 03:40:27 |
Я хочу создать новый столбец, который возвращает логическое значение на основе 2 столбцов
продукт | Продолжительность | duration_bool |
---|---|---|
замена шин | 01:16:51 | Правда |
замена масла | 01:06:00 | Правда |
замена шин | 04:03:04 | Ложный |
замена масла | 02:23:14 | Ложный |
замена масла | 03:40:27 | Ложный |
Является ли это правильным способом фактического использования функции в кадре данных? Мне трудно понять, как это на самом деле выполняет то, что мне нужно.
def sla_bool_checker(my_var):
#check if product is a tire change, if it is, check if duration is under 4 hours and return the Boolean in the new column
if df['product'] == 'tire change' :
df['duration_bool'] = df['duration'] < pd.Timedelta(4, unit='h')
#check if product is a oil change, if it is, check if duration is under 2 hours and return the Boolean
elif df['product'] == 'oil change' :
df['duration_bool'] < pd.Timedelta(2, unit='h')
Я не знаю, чего мне не хватает, но это ошибка кода.
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Ответ №1:
Создайте логический массив на основе ваших условий и назначьте его новому столбцу.
df['duration'] = df['duration'].apply(pd.Timedelta) # make sure duration has a dtype of Timedelta
df['duration_bool'] = ((df['product'] == 'tire change') amp; (df['duration'] < pd.Timedelta(4, unit='h'))) |
((df['product'] == 'oil change') amp; (df['duration'] < pd.Timedelta(2, unit='h')))
product duration duration_bool
0 tire change 0 days 01:16:51 True
1 oil change 0 days 05:06:00 False
2 tire change 0 days 02:03:04 True
3 oil change 0 days 06:23:14 False
4 oil change 0 days 03:40:27 False
что это значит
((df['product'] == 'tire change') amp; (df['duration'] < pd.Timedelta(4, unit='h')))
где продукт равен замене шин, а продолжительность составляет менее 4 часов.
|
или
((df['product'] == 'oil change') amp; (df['duration'] < pd.Timedelta(2, unit='h')))
где продукт равен замене масла, а продолжительность составляет менее 2 часов
Ответ №2:
Во-первых, durations
в ваших двух примерах не совпадают, это затрудняет сравнение входных и выходных результатов. Пожалуйста, проверьте это в следующий раз. Тогда вы можете использовать:
df.loc[df["product"] == "tire change", "duration_bool"] = pd.to_timedelta(df["duration"]) < pd.Timedelta(4, unit="h")
df.loc[df["product"] == "oil change", "duration_bool"] = pd.to_timedelta(df["duration"]) < pd.Timedelta(2, unit="h")
Это напрямую устанавливает значения строки duration_bool
как результат pd.Timedelta(...)
функции, но pd.to_timedelta(...)
гарантирует, что это временная шкала, с которой нужно сравнивать.
Это заводит тебя:
| | product | duration | duration_bool |
|---:|:------------|:-----------|:----------------|
| 0 | tire change | 01:16:51 | True |
| 1 | oil change | 01:06:00 | True |
| 2 | tire change | 04:03:04 | False |
| 3 | oil change | 02:23:14 | False |
| 4 | oil change | 03:40:27 | False |
Ответ №3:
Что я выяснил, так это то, что мне нужно было сделать return
оговорку в своем def sla_bool_checker
. Возвращаемое значение затем необходимо было применить к моему фрейму данных с помощью apply
. Я все еще не могу понять, как именно apply
это работает, но это сработало, я хотел бы иметь более глубокое объяснение для тех, кому оно нужно.
Я, вероятно, должен был использовать np.where() (все еще неясно, как это сделать), но ответ @it_is_chris на самом деле тоже хорошо сработал для меня! (спасибо, Крис)
с этого момента я просто продолжил исследования, так как мне действительно хотелось найти способ использовать для этого функцию. Возможно, это не идеально, но я многому научился.
вот код, который я использовал.
def sla_bool_checker(my_var):
#check if product is a tire change, if it is, check if duration is under 4 hours and return the Boolean in new column
if my_var['product'] == 'tire change' :
return my_var['duration'] < pd.Timedelta(4, unit='h')
#check if product is an oil change, if it is, check if duration is under 24 hours and return the Boolean
elif my_var['product'] == 'oil change' :
return my_var['duration'] < pd.Timedelta(2, unit='h')
затем я использовал
df['duration_bool'] = df.apply(sla_bool_checker, axis=1)
df
в результате чего
продукт | Продолжительность | duration_bool | |
---|---|---|---|
0 | замена шин | 01:16:51 | Правда |
1 | замена масла | 01:06:00 | Правда |
2 | замена шин | 04:03:04 | Ложный |
3 | замена масла | 02:23:14 | Ложный |
4 | замена масла | 03:40:27 | Ложный |
Комментарии:
1. Если какой-либо из ответов помог вам или дал новые идеи, авторы высоко оценят, если вы дадите положительный отзыв. Или примите ответ. Спасибо!