Populate value for data frame row based on condition

Viewed 412

Background

I have a dataset that looks like the following:

product_name    price
Women's pant    20.00
Men's Shirt     30.00
Women's Dress   40.00
Blue Shirt      30.00
...

I am looking to create a new column called

gender

which will contain the values Women,Men, or Unisex based in the string in the product_name

The desired result would look like this:

product_name    price   gender
Women's pant    20.00   women
Men's Shirt     30.00   men
Women's Dress   40.00   women
Blue Shirt      30.00   unisex

My Approach

I figured that first I should create a new column with a blank value for each row. Then I should loop through each row in the dataframe and check on the string df[product_name] to see if its a mens, womens, or unisex and fill out the respective gender row value.

Here is my code:

df['gender'] = ""
for product_name in df['product_name']:
    if 'women' in product_name.lower():
        df['gender'] = 'women'
    elif 'men' in product_name.lower():
        df['gender'] = 'men'
    else:
        df['gender'] = 'unisex'

However, I get the following result:

product_name    price   gender
Women's pant    20.00   men
Men's Shirt     30.00   men
Women's Dress   40.00   men
Blue Shirt      30.00   men

I would really appreciate some help here as I am new to python and pandas library.

4 Answers

You could use a list comprehension with if/else to get your output:

df['gender'] = ['women' if 'women' in word 
                else "men" if "men" in word
                else "unisex" 
                for word in df.product_name.str.lower()]

df

   product_name    price    gender
0   Women's pant    20.0    women
1   Men's Shirt     30.0    men
2   Women's Dress   40.0    women
3   Blue Shirt      30.0    unisex

Alternatively, you could use numpy select to achieve the same results:

cond1 = df.product_name.str.lower().str.contains("women")
cond2 = df.product_name.str.lower().str.contains("men")
condlist = [cond1, cond2]
choicelist = ["women", "men"]
df["gender"] = np.select(condlist, choicelist, default="unisex")

Usually, for strings, python's iteration is much faster; you have to test that though.

Try turning your for statement into a function and using apply. So something like -

def label_gender(product_name):
    '''product_name is a str'''
    if 'women' in product_name.lower():
        return 'women'
    elif 'men' in product_name.lower():
        return 'men'
    else:
        return 'unisex'

df['gender'] = df.apply(lambda x: label_gender(x['product_name']),axis=1)

A good breakdown of using apply/lambda can be found here: https://towardsdatascience.com/apply-and-lambda-usage-in-pandas-b13a1ea037f7

You can also use np.where + Series.str.contains,

import numpy as np

df['gender'] = (
    np.where(df.product_name.str.contains("women", case=False), 'women',
             np.where(df.product_name.str.contains("men", case=False), "men", 'unisex'))
)

    product_name  price  gender
0   Women's pant   20.0   women
1    Men's Shirt   30.0     men
2  Women's Dress   40.0   women
3     Blue Shirt   30.0  unisex

Use np.where .str.contains and regex first word` in phrase. So that;

#np.where(if product_name has WomenORMen, 1st Word in Phrase, otherwise;unisex)



 df['Gender']=np.where(df.product_name.str.contains('Women|Men')\
                      ,df.product_name.str.split('(^[\w]+)').str[1],'Unisex')


 
    product_name  price  gender
0   Women's pant   20.0   Women
1    Men's Shirt   30.0     Men
2  Women's Dress  640.0   Women
3    Blue Shirt    30.0  Unisex
Related