Reputation: 335
I have a dataframe with mixed data types and I would like to change the values of str cells (each consisting of two letters plus three numbers) so that uneven number become even numbers but the number decreases. AB123 should become AB122 while not changing the letter before it.
Here is an example dataframe with mixed types:
df = pd.DataFrame({'Opportunity':['AB122','AB123','AB125', 'AB124'],
'Quantity': [2, 3, 4, 1],
'Member': ["AACC", "AACC", "AACC", 'DDEE']})
print (df)
Opportunity Quantity Member
0 AB122 2 AACC
1 AB123 3 AACC
2 AB121 4 AACC
3 AB120 1 DDEE
I would like the outcome to be:
print (df2)
Opportunity Quantity Member
0 AB122 2 AACC
1 AB122 3 AACC
2 AB120 4 AACC
3 AB120 1 DDEE
Upvotes: 6
Views: 136
Reputation: 3770
df['Opportunity'] = df.Opportunity.apply(lambda x: x[:-3]+str(int(x[-3:]) - 1) if int(x[-3:]) % 2 != 0 else x)
Opportunity Quantity Member
0 AB122 2 AACC
1 AB122 3 AACC
2 AB120 4 AACC
3 AB120 1 DDEE
Upvotes: 0
Reputation: 88266
Here's one way slicing with pandas's str
accessor, subtracting the mod
by 2 to the integer part and concatenating back to the column using str.cat
:
d = df.Opportunity.str[-2:].astype(int)
df['Opportunity'] = df.Opportunity.str[:3].str.cat(d.sub(d.mod(2)).astype(str))
Opportunity Quantity Member
0 AB122 2 AACC
1 AB122 3 AACC
2 AB120 4 AACC
3 AB120 1 DDEE
Input dataframe:
print(df)
Opportunity Quantity Member
0 AB122 2 AACC
1 AB123 3 AACC
2 AB121 4 AACC
3 AB120 1 DDEE
Upvotes: 2
Reputation: 71600
Try:
df['Opportunity'] = df['Opportunity'].str[:2] + np.where(df['Opportunity'].str[2:].astype(int) % 2, df['Opportunity'].str[2:].astype(int).sub(1).astype(str), df['Opportunity'].str[2:])
And now:
print(df)
Is:
Member Opportunity Quantity
0 AACC AB122 2
1 AACC AB122 3
2 AACC AB120 4
3 DDEE AB120 1
Upvotes: 3
Reputation: 3624
df = pd.DataFrame({'Opportunity':['AB122','AB123','AB125', 'AB124'],
'Quantity': [2, 3, 4, 1],
'Member': ["AACC", "AACC", "AACC", 'DDEE']})
even = lambda x: int(x) % 2 == 0
df['Opportunity'] = df['Opportunity'].apply(lambda x: x[:2] + (x[2:] if even(x[2:]) else str(int(x[2:]) -1)))
print(df)
output:
Opportunity Quantity Member
0 AB122 2 AACC
1 AB122 3 AACC
2 AB124 4 AACC
3 AB124 1 DDEE
Upvotes: 0