tender
tender

Reputation: 71

Python pandas if statement based off of boolean qualifier

I am try to do an IF statement where it keeps my currency pairs in alphabetic ordering (i.e. USD/EUR would flip to EUR/USD because E alphabetically comes before U, however CHF/JPY would stay the same because C comes alphabetically before J.) Initially I was going to write code specific to that, but realized there were other fields I'd need to flip (mainly changing a sign for positive to negative or vice versa.)

So what I did was write a function to create a new column and make a boolean identifier as to whether or not the field needs action (True) or not (False).

def flipFx(ccypair):
    first = ccypair[:3]
    last = ccypair[-3:]
    if(first > last):
        return True
    else:
        return False

brsPosFwd['Flip?'] = brsPosFwd['Currency Pair'].apply(flipFx)    

This works great and does what I want it to.

Then I try and write an IF statement to use that field to create two new columns:

if brsPosFwd['Flip?'] is True:
    brsPosFwd['CurrencyFlip'] = brsPosFwd['Sec Desc'].apply(lambda x: 
x.str[-3:]+"/"+x.str[:3])
    brsPosFwd['NotionalFlip'] = -brsPosFwd['Current Face']
else:
    brsPosFwd['CurrencyFlip'] = brsPosFwd['Sec Desc']
    brsPosFwd['NotionalFlip'] = brsPosFwd['Current Face']

However, this is not working properly. It's creating the two new fields, CurrencyFlip and NotionalFlip but treating every record like it is False and just pasting what came before it.

Does anyone have any ideas?

Upvotes: 1

Views: 323

Answers (1)

jpp
jpp

Reputation: 164673

Pandas uses vectorised functions. You are performing operations on entire series objects as if they were single elements.

You can use numpy.where to vectorise your calculations:

import numpy as np

brsPosFwd['CurrencyFlip'] = np.where(brsPosFwd['Flip?'],
                                     brsPosFwd['Sec Desc'].str[-3:]+'/'+brsPosFwd['Sec Desc'].str[:3]),
                                     brsPosFwd['Sec Desc'])

brsPosFwd['NotionalFlip'] = np.where(brsPosFwd['Flip?'],
                                     -brsPosFwd['Current Face'],
                                     brsPosFwd['Current Face'])

Note also that pd.Series.apply should be used as a last resort; since it is a thinly veiled inefficient loop. Here you can simply use the .str accessor.

Upvotes: 5

Related Questions