Серия карт панд со строковым рисунком

#python #dataframe #mapping

Вопрос:

Привет, я хотел бы отобразить серию панд, используя строковый шаблон

 s=pd.DataFrame([['AMcU8', 10], ['AM8v', 15], ['ASw9', 14],['ASw7', 14]], columns = ['Code', 'Quantity'])

s["newcode"]=s["Code"].map({"AM.*8.*" : "AM8", "AS.*9.*" : "AS9"})
 

но я понимаю это:

    Code  Quantity newcode
0  AMcU8       10     NaN
1  AM8v        15     NaN
2  ASw9        14     NaN
3  ASw7        14     NaN
 

вместо:

    Code  Quantity newcode
0  AMcU8       10     AM8
1  AM8v        15     AM8
2  ASw9        14     AS9
3  ASw7        14     NaN
 

есть идеи? это нормально-получить НэН, когда она не находит совпадения

Комментарии:

1. Вы просто хотите удалить строчную букву из исходного кода?

2. нет, это тоже может быть верхний регистр

Ответ №1:

Вы можете использовать Series.replace с параметром regex , установленным в вашем словаре сопоставлений (документация).:

 s["newcode"] = s["Code"].replace(regex={"AM.*8.*":"AM8", "AS.*9.*": "AS9"})
 

который производит:

     Code    Quantity    newcode
0   AMcU8   10          AM8
1   AM8v    15          AM8
2   ASw9    14          AS9
3   ASw7    14          ASw7
 

Обратите внимание, что несоответствующие шаблоны остаются неизменными.

Ответ №2:

Насколько мне известно, для выполнения этой операции нет прямой функции.

Вы можете сделать это с помощью apply() и re и выполнить итерацию по вашему словарю сопоставления следующим образом:

 mapping = {"AM.*8" : "AM8", "AS.*9" : "AS9"}
import re

def regex_mapping(x):
    for k, v in mapping.items():
        if re.match(k, x):
            return re.sub(k, v, x)
    return x

s['Code'].apply(regex_mapping)
 

Выход:

 0     AM8
1     AM8
2     AS9
3    ASw7
Name: Code, dtype: object
 

Ответ №3:

Насколько я знаю, вы не можете предоставить ключи регулярных выражений для Series.map() .

Однако это делает то, что вам нужно:

 import re
import pandas as pd

s = pd.DataFrame([['AMcU8', 10], ['AM8', 15], ['ASw9', 14], ['ASw7', 14]], columns=['Code', 'Quantity'])


def regex_replace(x, map: dict = None):
    for regex, replacement in map.items():
        if re.match(regex, x):
            return replacement
    else:
        return x


s["newcode"] = s["Code"].apply(regex_replace, map={"AM.*8": "AM8", "AS.*9": "AS9"})
 

Или если вы часто применяете это к большим кадрам данных и хотите, чтобы в этом случае это было немного быстрее и эффективнее:

 import re
import pandas as pd
from functools import partial

s = pd.DataFrame([['AMcU8', 10], ['AM8', 15], ['ASw9', 14], ['ASw7', 14]], columns=['Code', 'Quantity'])


def regex_replace(map: dict = None, x=None):
    for regex, replacement in map.items():
        if regex.match(x):
            return replacement
    else:
        return x

mapping = partial(regex_replace, {re.compile("AM.*8"): "AM8", re.compile("AS.*9"): "AS9"})
s["newcode"] = s["Code"].apply(mapping)