Pandas和apply函数用于匹配字符串

3

我有一个包含各种链接的df列,其中一些链接包含字符串"search"

我想创建一个应用于该列的函数,返回一个包含"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'对象没有属性'str'

我想在调用str.contains()时可能漏掉了一些东西。
3个回答

2

我认为你需要使用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

时间

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

我为多种情况提供了解决方案,apply方法比np.where更快。 - jezrael

2

.str 适用于整个 Series,但在这里你正在处理 Series 中的值。

你可以采取以下任一方式: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'))

如果我想指定一个elif条件怎么办:如果主页则为“homepage”,否则为“other”? - chopin_is_the_best
解决方法如下: df['link_type'] = np.where(df.referrer.str.contains(search),'搜索', np.where(df.referrer.str.contains(profile),'个人资料', np.where(df.referrer.str.contains(homepage), '主页', np.where(df.referrer.str.contains(login),'登录','其他')))) - chopin_is_the_best

1
你可以使用列表推导式来查找链接中的单词搜索:
例如:
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 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接