regex python pandas使用map和正则表达式

t30tvxxf  于 2023-05-19  发布在  Python
关注(0)|答案(5)|浏览(137)

我有一个命令:

dealer = {
    'ESSELUNGA': 'Spesa',
    'DECATHLON 00000120': 'Sport',
    'LEROY MERLIN': 'Casa',
    'CONAD 8429': 'Spesa',
    'IKEA': 'Casa',
    'F.LLI MADAFFARI': 'Spesa',
    'SUPERMERCATO IL GIGANT': 'Spesa',
    'NATURASI SPA': 'Spesa',
    'ESSELUNGA SETTIMO MILANE': 'Spesa'
}

我想把它Map到一个pandas df:

entries.Categoria = entries.Commerciante.map(dealer)

有没有一种方法可以使用正则表达式来匹配“Commerciante”列上的Map?这样,我可以将dealer改写为:

dealer = {
    'ESSELUNGA': 'Spesa',
    'DECATHLON': 'Sport',
    'LEROY MERLIN': 'Casa',
    'CONAD': 'Spesa',
    'IKEA': 'Casa',
    'F.LLI MADAFFARI': 'Spesa',
    'SUPERMERCATO IL GIGANT': 'Spesa',
    'NATURASI SPA': 'Spesa',
    'ESSELUNGA SETTIMO MILANE': 'Spesa'
}

并匹配“DECATHLON”和“DECATHLON 00000120”

xyhw6mcr

xyhw6mcr1#

可以使用正则表达式的dict解析来重写key。re python模块用于执行此任务,命令为sub。替换键如下所示:

import re
dealer = {re.sub(r'(\W)[0-9]+',r'\1',k).strip():dealer[k] for k in dealer}

整个示例给出:

import re
dealer = {
    'ESSELUNGA': 'Spesa',
    'DECATHLON 00000120': 'Sport',
    'LEROY MERLIN': 'Casa',
    'CONAD 8429': 'Spesa',
    'IKEA': 'Casa',
    'F.LLI MADAFFARI': 'Spesa',
    'SUPERMERCATO IL GIGANT': 'Spesa',
    'NATURASI SPA': 'Spesa',
    'ESSELUNGA SETTIMO MILANE': 'Spesa'
}
dealer = {re.sub(r'(\W)[0-9]+',r'\1',k).strip():dealer[k] for k in dealer}
ruarlubt

ruarlubt2#

我认为你的问题是你试图一步做两件事。
首先清理数据,然后Map它。
pandas系列包含了很多很好的字符串函数,这些函数可以在清理数据时派上用场。Here is a good reference to the string methods
使用字符串方法清理数据后,Map数据将非常容易。

pokxtpni

pokxtpni3#

另一种方法是使用df.replace。如果你将DECATHLON键设置为一个正则表达式,比如dealer中的r'^DECATHLON.*',你可以这样做,

dealer = {
    'ESSELUNGA': 'Spesa', 
    r'DECATHLON.*': 'Sport',
    'LEROY MERLIN': 'Casa',
    'CONAD 8429': 'Spesa',
    'IKEA': 'Casa',
    'F.LLI MADAFFARI': 'Spesa',
    'SUPERMERCATO IL GIGANT': 'Spesa',
    'NATURASI SPA': 'Spesa',
    'ESSELUNGA SETTIMO MILANE': 'Spesa'
}

df['Commerciante'] = df['Commerciante'].replace(regex=dealer)
aurhwmvo

aurhwmvo4#

为什么不使用apply和修改后的字典查找:

In [14]: [dname for dname in dealer if 'DECATHLON' in dname]
Out[14]: ['DECATHLON 00000120']

像这样涂抹-

df['Commerciante'] = df['Commerciante'].apply(lambda v: [dname for dname in dealer if dname.startswith('DECATHLON')][0])
n9vozmp4

n9vozmp45#

谢谢你们所有人。我用你的建议解决了我的问题。我定义了一个新函数:

def dealer_replace(dealer_dict, text):

    regex = re.compile("(%s)" % "|".join(map(re.escape, dealer_dict.keys())))

    if regex.search(text):
        ret = regex.search(text)
        return dealer_dict[ret.group()]
    else:
        return None

并与apply一起使用

entries['Categoria'] = entries['Commerciante'].apply(lambda v: dealer_replace(dealer, str(v)))

相关问题