2016-09-27 5 views
1

У меня есть столбец df, содержащий различные ссылки, некоторые из которых содержат строку "search".Pandas и применить функцию для соответствия строке

Я хочу создать функцию, которая - применяемая к столбцу - возвращает столбец, содержащий "search" или "other".

Я пишу функцию, как:

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

df['link'].apply(page_type) 

, но он дает мне ошибку, как:

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

Я предполагаю, что я что-то отсутствует при вызове str.contains().

ответ

1

Я думаю, что вам нужно numpy.where:

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 
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 

Timings:

#[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 
+0

добавить решение для нескольких условий, 'apply' решение быстрее, так как' np.where' , – jezrael

1

.str относится ко всей серии, но здесь вы имеете дело со значением внутри серии ,

Вы можете сделать: df['link'].str.contains(search)
Или, как вы хотите: df['link'].apply(lambda x: 'Search' if search in x else 'Other')

Редактировать

Более универсальный способ:

def my_filter(x, val, c_1, c_2): 
    return c_1 if val in x else c_2 

df['link'].apply(lambda x: my_filter(x, 'homepage', 'homepage', 'other')) 
+0

И что, если я хочу указать условие elif: если домашняя страница тогда «домашняя страница в противном случае» другая? – xxxvinxxx

+0

разрешила это как: df ['link_type'] = np.where (df.referrer.str.contains (поиск), 'Поиск', np.where (df.referrer.str.contains (профиль), 'Профиль', np.where (df.referrer.str.contains (домашняя страница), 'Домашняя страница', np.where (df .referrer.str.contains (login), 'Login', 'Other')))) – xxxvinxxx

+0

Я отредактировал с вашим примером – Orelus

0

Вы можете использовать также list comprehesion, если вы хотите найти слово поиска по ссылке:

Fo Например:

df['Search'] = [('search' if 'search' in item else 'other') for item in df['link']] 

Выход:

ColumnA      link Search 
0  a  http://word/12/word other 
1  b  https://search-125.php search 
2  c  http://news-8282.html other 
3  d http://search-hello-1.html search 

Создание функции:

def page_type(x, y): 
    df[x] = [('search' if 'search' in item else 'other') for item in df[y]] 

page_type('Search', 'link') 

In [6]: df 
Out[6]: 
    ColumnA      link Search 
0  a   http://word/12/word other 
1  b  https://search-125.php search 
2  c  http://news-8282.html other 
3  d http://search-hello-1.html search 
Смежные вопросы