Python 在dataframe上使用正则表达式创建新列的多个条件

Python 在dataframe上使用正则表达式创建新列的多个条件,python,regex,pandas,numpy,dataframe,Python,Regex,Pandas,Numpy,Dataframe,因此,我有一个类似于熊猫的df: Name URL X http://www.x.com/abc/xyz/url.html X http://www.x.com/yyz/hue/end.html Othername http://website.othername.com/abc.html Othername http://home.othername.com/someword/word.html Example http:/

因此,我有一个类似于熊猫的df:

Name        URL
X           http://www.x.com/abc/xyz/url.html
X           http://www.x.com/yyz/hue/end.html
Othername   http://website.othername.com/abc.html
Othername   http://home.othername.com/someword/word.html
Example     http://www.example.com/999/something/index.html
我想使用regex(我猜)添加一个“Extract”列,如下所示:

Name        URL                                              Extract
X           http://www.x.com/abc/xyz/url.html                abc
X           http://www.x.com/yyz/hue/end.html                yyz 
Othername   http://website.othername.com/abc.html            website
Othername   http://home.othername.com/someword/word.html     home
Example     http://www.example.com/999/something/index.html  999
正如您可能看到的,我想提取的部分因网站而异。因此,对于“Name”下的值“X”,我必须应用一个正则表达式模式。对于“Othername”,另一种模式

我有6种不同的(和6种不同的模式)用于此

我尝试使用“where”,但我可以使它只适用于其中一个网站,而不考虑多种条件。详情如下:

df['Extract'] = np.where(df['Name'] == 'X', df.URL.str.extract(r'www\.x\.com\/(.*?)/'),'')
我还尝试为此创建一个函数:

def ext(c):
    if c['Name'] == 'X':
        c.URL.str.extract(r'www\.x\.com\/(.*?)/')
    elif c['Name'] == 'Example':
        c.URL.str.extract(r'www\.example\.com\/(.*?)/')
    (...)
    else:
        return ''

df['Extract'] = df.apply(ext)
df
我如何才能使“名称”下的不同str工作?

尝试以下方法:

In [87]: df['Extract'] = (df.URL.replace([r'http[s]?://www\.[^/]*\/', r'http[s]?://'], ['',''], regex=True)
    ...:                    .str.extract(r'([^/.]*)', expand=False))
    ...:

In [88]: df
Out[88]:
        Name                                              URL  Extract
0          X                http://www.x.com/abc/xyz/url.html      abc
1          X                http://www.x.com/yyz/hue/end.html      yyz
2  Othername            http://website.othername.com/abc.html  website
3  Othername     http://home.othername.com/someword/word.html     home
4    Example  http://www.example.com/999/something/index.html      999

您可以使用条件正则表达式:

import re
rx = re.compile(r'https?://(www)?(?(1)[^/+]+/([^/]+)|([^.]+))')
def extract(col):
    m = rx.match(col)
    if m is not None:
        return m.group(3) if m.group(3) is not None else m.group(2)
    else:
        return ''

df['Extract'] = df['URL'].apply(extract)
当子域本身为
www
else时,假设您正在查找
/
之后的第一部分。
分解如下:

https?://   # match http:// or https.//
(www)?      # capture www into group 1 if it is there
(?(1)       # check if it was matched
    [^/+]+/ # ... and if so fast forward ...
    ([^/]+) # capture it into group 2
|           # else
    ([^.]+) # otherwise capture the part directly after http://
)           # into group 3
请参阅。

df.col.apply(extract)解决方案帮助我将不同的正则表达式应用于同一列,而无需替换以前提取的值--woot!