Pandas and apply function to match a string
<p>I have a df column containing various links, some of them containing the string <code>"search"</code>.</p>

<p>I want to create a function that - being applied to the column - returns a column containing <code>"search"</code> or <code>"other"</code>.</p>

<p>I write a function like:</p>

<pre><code>search = 'search'
def page_type(x):
if x.str.contains(search):
    return 'Search'
else:
    return 'Other'   

df['link'].apply(page_type)
</code></pre>

<p>but it gives me an error like:</p>

<blockquote>
  <p>AttributeError: 'unicode' object has no attribute 'str'</p>
</blockquote>

<p>I guess I'm missing something when calling the str.contains().</p>

<p>I think you need <a href="http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.where.html" rel="nofollow"><code>numpy.where</code></a>:</p>

<pre><code>df = pd.DataFrame({'link':['search','homepage d','login dd', 'profile t', 'ff']})

print (df)
         link
0      search
1  homepage d
2    login dd
3   profile t
4          ff
</code></pre>



<pre><code>search = 'search'
profile = 'profile'
homepage = 'homepage'
login = "login"

def page_type(x):
    if search in x:
        return 'Search'
    elif profile in x:
        return 'Profile'
    elif homepage in x:
        return 'Homepage'
    elif login in x:
        return 'Login'
    else:
        return 'Other'  

df['link_new'] = df['link'].apply(page_type)

df['link_type'] = np.where(df.link.str.contains(search),'Search', 
                  np.where(df.link.str.contains(profile),'Profile', 
                  np.where(df.link.str.contains(homepage), 'Homepage', 
                  np.where(df.link.str.contains(login),'Login','Other')))) 


print (df)
         link  link_new link_type
0      search    Search    Search
1  homepage d  Homepage  Homepage
2    login dd     Login     Login
3   profile t   Profile   Profile
4          ff     Other     Other
</code></pre>

<p><strong>Timings</strong>:</p>

<pre><code>#[5000 rows x 1 columns]
df = pd.DataFrame({'link':['search','homepage d','login dd', 'profile t', 'ff']})
df = pd.concat([df]*1000).reset_index(drop=True)

In [346]: %timeit df['link'].apply(page_type)
1000 loops, best of 3: 1.72 ms per loop

In [347]: %timeit np.where(df.link.str.contains(search),'Search', np.where(df.link.str.contains(profile),'Profile', np.where(df.link.str.contains(homepage), 'Homepage', np.where(df.link.str.contains(login),'Login','Other'))))
100 loops, best of 3: 11.7 ms per loop
</code></pre>

python string pandas condition contains