I have the below code:
data['ShortLongFlag'] = data['End DateTime'].apply(lambda x:
-1 if (x.month == 3 and x.date() in shortlongdates == True) else (1 if (x.month == 10 and x.date() in shortlongdates == True) else 0))
What I'm trying to do is the following:
Create a new column in my dataframe which is populated with either -1, 0 or 1 based on the following conditions:
- -1 if the month of the value in my datetime column is equal to 3 and the date is in my list of dates called "shortlongdates"
- 1 if the month of the value in my datetime column is equal to 10 and the date is in my list of dates called "shortlongdates"
- 0 otherwise
Right now all the values are being outputted as 0 in the new column... why?
CodePudding user response:
The reason for this problem is chaining comparison operators
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
Comparisons, including membership tests and identity tests have same precedence.
i.e.
x.month == 3 and x.date() in shortlongdates == True
is same as
x.month == 3 and x.date() in shortlongdates and shortlongdates == True
Note that it can be written as x.month == 3 and x.date() in shortlongdates
, or use brackets. However as already stated in comments this lambda is better written as regular function.
def replace_value(x):
if x.date() in shortlongdates:
return {3:-1, 10:1}.get(x.month, 0)
return 0
I will leave up to you to convert this back to [simpler] lambda if you insist.
CodePudding user response:
So we have this unreadable thing:
lambda x: -1 if (x.month == 3 and x.date() in shortlongdates == True) else (1 if (x.month == 10 and x.date() in shortlongdates == True) else 0)
Let's write it out as a standard function:
def filterfn(x):
if x.month == 3 and x.date() in shortlongdates:
return -1
elif x.month == 10 and x.date() in shortlongdates:
return 1
else:
return 0
That removing some stranger tests (redundant == True) and brackets.
Is x.date()
really a callable? Should it be x.date
?
Without seeing your data
and listofdates
it's impossible to say how this might fail, but at least we can see what it's doing.