Home > front end >  Using Operator Module to Pass 'Nothing'
Using Operator Module to Pass 'Nothing'

Time:03-10

The code below executes fine when the third condition and choice are removed.

I am using the operator module to pass in a tilde.

The problem is that there are times where I want to NOT take the inverse of these statements, and other times that I do.

In the conditions section, I am passing None to avoid using an operator there, but this is obviously incorrect. I also tried using an if statement to avoid using the inverse operator, i but don't know how to connect if statements with an &.

FWIW - I realize I could define all the possible specs individually, but there are more than a dozen of them, so this approach seemed a lot better to me.

import pandas as pd
import numpy as np
from operator import lt as less_than, invert as invrt
import math

infinity = math.inf

names = [
    [5, 'b0524', .02, 'shoes'],
    [1, 'b0874', .12, 'toy'],
    [10, 'b0321', .11, 'b0321'],
    [7, 'b0781', .60, 'car'],
    [8, 'b0321', .16, 'plane']
]
df = pd.DataFrame(names, columns=['orders', 'id', 'acos', 'term'])

acos = .15
exclude = ['toy']


def specs(df, min_orders, max_orders, operator, acos, exclude, tilde1, tilde2):
    return (
    (df['orders'] >= min_orders) &
    (df['orders'] <= max_orders) &
    (operator(df['acos'], acos)) &
    (tilde1(df['term'].str.contains('|'.join(exclude)))) &
    (tilde2(df['term'].str.contains(pat = 'b0', case = False)))
    )


def strategy(df, acos, exclude):
    conditions = ([
        specs(df, 3, infinity, less_than, acos, exclude, invrt, invrt),
        specs(df, 1, 2, less_than, acos, exclude, invrt, invrt),   
        specs(df, 1, 2, less_than, acos, exclude, None, None),    
    ])


    choices = [
        'strat1',
        'strat2',
        'strat3'
    ]


    df['strategy'] = np.select(conditions, choices, default='NA')
    return df


strategy(df, acos, exclude)

print(df)

CodePudding user response:

I think something like this should work. The idea is to use a conditional expression (aka ternary operator) to toggle between actually calling tilde2 vs simply returning a like-sized result filled with True (there may be a more elegant way to do this, but I have gotten the array of True by comparing df['term'] to itself for equality, which will always be True).

def specs(df, min_orders, max_orders, operator, acos, exclude, tilde1, tilde2):
    return (
    (df['orders'] >= min_orders) &
    (df['orders'] <= max_orders) &
    (operator(df['acos'], acos)) &
    (tilde1(df['term'].str.contains('|'.join(exclude)))) &
    (df['term'] == df['term'] if tilde2 is None else tilde2(df['term'].str.contains(pat = 'b0', case = False)))
    )
  • Related