Pandas dataframe search for string and return False values

Viewed 461

I have a dataframe like this

   Index    A
0      1  cat
1      2  dog
2      3  bot
3      4  fly

I would like to create two columns depending on if column A contains the letters 'a OR b OR c'

Intended outcome:

Index| A | yes |   no    |
--------------------------
1    |cat| cat |         |
2    |dog|     |   dog   | 
3    |bot| bot |         |
4    |fly|     |   fly   |

At the moment I have

abc = ['a', 'b', 'c']
abc = '|'.join(abc)

df['yes'] = df[df['A'].str.contains(abc)]['A']
df['no'] = df[df['A'].str.contains(abc) == False]['A']

The selection works fine for yes, but for no, the following error occurs

ValueError: too many values to unpack (expected 3)

The column is created, but because of the error future functions (eg. info()) seem to break as a result.

This could be because 3 results are given for checks on a, b and c. Is there a way to return the False values correctly in this instance? Thanks

3 Answers

This looks like a job for set_index and unstack:

m = df['A'].str.contains(abc).replace({True: 'yes', False: 'no'})
m
 
0    yes
1     no
2    yes
3     no
Name: A, dtype: object

df.set_index(['Index', m])['A'].unstack(fill_value='')

A       no  yes
Index          
1           cat
2      dog     
3           bot
4      fly     

Using your method, small change in code you could get the right output.

abc = ['a', 'b', 'c']
abc = '|'.join(abc)

df['yes'] = df[df['A'].str.contains(abc)]['A']
df['no'] = df[~df['A'].str.contains(abc)]['A']

Another way;

Chain np.where, str.contains and ''.join() to populate yes and no. pivot the frame as follows

df['status']=np.where(df.A.str.contains('|'.join(['a','b','c'])),'yes','no')
    df.pivot(index='A', columns='status',values='A').fillna('').reset_index()

status    A   no  yes
0       bot       bot
1       cat       cat
2       dog  dog     
3       fly  fly  
Related