Search code examples
pythonpandaslambdaconditional-statementsapply

Pandas: Lambda Function using a conditional as well as an operator (Or, and))


I am working through my comprehension of lambdas functions as it pertains to pandas. I am trying to create a new column based on if a certain word appears in column (A) ("Appeals","Audit","Assessment")

However I am receiving an error of:

AttributeError: 'str' object has no attribute 'str'

d = {"A":["Assessment Division","Division of Appeals","Calgary Audit","Halifax Market","Georgian Markers"],
"B":[100,300,400,500,400]

sample = pd.DataFrame(d)

sample["results"] = sample["A"].apply(lambda x: "Invoice" if x.str.contains("Audit") or x.str.contains("Appeals") or x.str.contains("Assessment") else "NoAction")


I have also tried this to attempt to shorten my code but receive the same error:

d = {"A":["Assessment Division","Division of Appeals","Calgary Audit","Halifax Market","Georgian Markers"],
"B":[100,300,400,500,400]

sample = pd.DataFrame(d)

reqs = ["Audit","Appeals","Assessment"]

sample["results"] = sample["A"].apply(lambda x: "Invoice" if x.str.contains().isin(reqs) else "NoAction")


Solution

  • You can use any() to check if the string contains any word from your reqs:

    reqs = ["Audit","Appeals","Assessment"]
    
    mask = sample['A'].apply(lambda x: any(r in x for r in reqs))
    sample['results'] = np.where(mask, 'Invoice', 'NoAction')
    
    print(sample)
    

    Prints:

                         A    B   results
    0  Assessment Division  100   Invoice
    1  Division of Appeals  300   Invoice
    2        Calgary Audit  400   Invoice
    3       Halifax Market  500  NoAction
    4     Georgian Markers  400  NoAction
    

    EDIT: One-liner:

    sample['results'] = sample['A'].apply(lambda x: 'Invoice' if any(r in x for r in reqs) else 'NoAction')