Нет необходимости выполнять цикл for для выполнения операций такого типа в пандах. Это можно сделать с помощью маски (см. на этой странице документации для получения дополнительной информации о булевой индексации в пандах). Для бездействия:
max_rate = 20
max_time_mins = vehicle['max time'] * 1440
Это умножается на 1440 поэлементно. То есть каждая строка умножается на константу.
x = vehicle['Minutes'] >= max_time_mins
# Output
# 0 True
# 1 False
# 2 False
# 3 False
# 4 False
# 5 False
# 6 False
# dtype: bool
Это сравнение также проводится поэлементно. Следовательно, выходные данные представляют собой булеву серию той же длины, которая будет содержать True
, если элемент этой строки удовлетворяет условию, и False
в противном случае.
Вот почему вы получили ошибку Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()
, когда пытались выполнить if x == True:
, потому что оператор if не работает поэлементно.
Однако при логическом индексировании поведение if ... else ... может быть легко воспроизведено с использованием уже определенной маски и неэлементного оператора not ~
:
cost = pd.Series(np.empty(vehicle.shape[0])) # initialize a Series with the same shape
cost.loc[x] = ((((vehicle['Minutes'][x]%1440)/60)*vehicle['rate'][x])+ (vehicle['Minutes'][x]/1440) * max_rate) # Equivalent to if
cost.loc[~x] = ((vehicle['Minutes'][~x]/60)*vehicle['rate'][~x]) # Equivalent to else
# Output
# 0 40.000000
# 1 52.616667
# 2 48.000000
# 3 48.000000
# 4 83.941667
# 5 26.250000
# 6 25.033333
# dtype: float64
Который также можно добавить непосредственно к исходному фрейму данных в качестве нового столбца:
vehicle.loc[x, 'cost'] = ((((vehicle['Minutes'][x]%1440)/60)*vehicle['rate'][x])+ (vehicle['Minutes'][x]/1440) * max_rate)
# Here vehicle has values in rows where x is true and NaN everywhere else
vehicle.loc[~x, 'cost'] = ((vehicle['Minutes'][~x]/60)*vehicle['rate'][~x])
# The rest of the rows are filled