DFF :

    Sample  AlmostFinal  
    1          KOPLA234        
    1          KOPLA234
    2          RWPLB253
    3          MMPLA415
    3          MMPLA415 

Мне нужно заменить KOPL и RWP и MM на KOLPOL, и последний символ a / b должен остаться. Итак, результат должен быть:

    Sample  AlmostFinal  Final
    1          KOPLA234  KOLPOLA234      
    1          KOPLA234  KOLPOLA234
    2          RWPLB253  KOLPOLB253
    3          MMPLA415  KOLPOLA415
    3          MMPLA415  KOLPOLA415

Я попытался сделать это путем замены:

    dfF['Final'] = (dfF['AlmostFinal'].replace({'KOPL':'KOLPOL'}, regex = True))
    dfF['Final'] = (dfF['AlmostFinal'].replace({'RWP':'KOLPOL'}, regex = True))
    dfF['Final'] = (dfF['AlmostFinal'].replace({'MMPL':'KOLPOL'}, regex = True))

И: Если я прокомментирую, 2-я и 3-я строка заменяет KOPL.

Когда я комментирую 1-й и 3-й замените RWP работ.

Но когда я раскомментирую все и пытаюсь запустить все 3 строчки, работает только последняя. Зачем? В другом скрипте у меня есть похожий код, и он меняется целиком, а целые строки работают.

1
martin 28 Июн 2019 в 09:07

3 ответа

Лучший ответ

Вы можете использовать один replace вызов с regex=True:

df['Final'] = df['AlmostFinal'].replace(
    [r'KOPL', r'RWP.*?(?=A|B)', r'MM.*(?=A|B)'], 'KOLPOL', regex=True)
df

   Sample AlmostFinal       Final
0       1    KOPLA234  KOLPOLA234
1       1    KOPLA234  KOLPOLA234
2       2    RWPLB253  KOLPOLB253
3       3    MMPLA415  KOLPOLA415
4       3    MMPLA415  KOLPOLA415

Мы хотим иметь возможность обрабатывать различное количество символов между подстрокой и последним символом, поэтому здесь будет полезно использовать регулярное выражение с предпросмотром.


Дальнейшее обобщение возможно. Просто определите ваши подстроки, а затем вставьте заглядывание через список комп.

pat = ['KOPL', 'RWP', 'MM']
df['Final'] = df['AlmostFinal'].replace(
    [rf'{p}.*(?=A|B)' for p in pat], 'KOLPOL', regex=True)  # need python3.6+
df

   Sample AlmostFinal       Final
0       1    KOPLA234  KOLPOLA234
1       1    KOPLA234  KOLPOLA234
2       2    RWPLB253  KOLPOLB253
3       3    MMPLA415  KOLPOLA415
4       3    MMPLA415  KOLPOLA415

Если вы хотите заменить определенные подстроки, решение будет немного более простым.

pat = ['KOPL', 'RWPL', 'MMPL']
df['AlmostFinal'].replace(pat, 'KOLPOL', regex=True)

0    KOLPOLA234
1    KOLPOLA234
2    KOLPOLB253
3    KOLPOLA415
4    KOLPOLA415
Name: AlmostFinal, dtype: object

Никаких других изменений не требуется. Для более общих замен см. Выше.

1
cs95 28 Июн 2019 в 06:23

И: Если я прокомментирую, 2-я и 3-я строка заменяет KOPL. Когда я комментирую 1-й и 3-й замените RWP работ. Но когда я раскомментирую все и пытаюсь запустить все 3 строчки, работает только последняя. Зачем?

Так как замена создает новый фрейм данных, и поскольку вы всегда выполняете замену одного исходного фрейма данных, каждая замена отбрасывает результат предыдущего.

Либо делайте все замены одновременно, например используйте регулярное выражение или, я полагаю, один dict с несколькими значениями (не знаю, почему вы действительно используете dict для одного значения здесь:

{
    'KOPL':'KOLPOL',
    'RWP':'KOLPOL',
    'MMP':'KOLPOL',
}

Или выполнить каждую замену в результате предыдущего (либо цепная замена, либо вторая и третья должны работать на df['Final']).

1
Masklinn 28 Июн 2019 в 06:15

Вы должны выполнить одно задание, а не три. В противном случае каждое следующее назначение перезаписывает результаты предыдущего назначения.

dfF['Final'] = dfF['AlmostFinal']\
               .replace({'KOP|RWP|MMP': 'KOLPO'}, regex = True)
1
DYZ 28 Июн 2019 в 06:22