Если значение находится в этом списке и где-то в значении столбца, могу ли я заменить это значение столбца значением списка? Фрейм данных Панд

#python #pandas #replace #re

Вопрос:

Существует МНОГО документации об этом, но я не могу этого понять.

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

 active_crews = ["CREW #101", "CREW #102", "CREW #203", "CREW #301", "CREW #404", "CREW #501", "CREW #406", "CREW #304", "CREW #701", "CREW #702", "CREW #703", "CREW #704", "CREW #705", "CREW #706",
                "CREW #707" "CREW #708", "CREW #801", "CREW #802", "CREW #803", "CREW #805"]
 

Пример данных, которые я хочу заменить. и да, форматирование также имеет небольшие различия:

 Debris Crew WO# 
REFER TO IAP 12/16 TO 12/19 CREW #405
REFER TO IAP 06/02 TO 06/05 CREW #406
REFER TO IAP 03/24TO 03/27 CREW # 803
 

Ожидаемый выход

 Debris Crew WO#
CREW #405
CREW #406
CREW #803
 

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

Коды, которые я пробовал:

1)

 df.loc[df['Debris Crew WO#'] == active_crews, 'Debris Crew WO#']
# doesn't work. This was done before research lol I get the following error, which makes sense
# ValueError: ('Lengths must match to compare', (2216,), (19,))
 
 df.loc[:, ['Place Holder']] = df.loc[:, 'Debris Crew WO#'].str[28:]
# this code "works" but due to different formatting i get data back like this:
8   REW #406
9   CREW #406
# not very effective and can not be relied on. I hate hard coding anything.
 
 df.loc[:, ['Place Holder']] = df.loc[:, 'Debris Crew WO#'].str[26:]
df.loc[:, ['Place Holder']] = df[['Place Holder']].str.split().join(" ")
# tried this due to I have this filter for specials characters with a for loop in a different code and yet I get this error and I have no clue why. Works on my other codes with no problems

#AttributeError: 'DataFrame' object has no attribute 'str'

# even if I use .loc I get the same error:
df.loc[:, ['Place Holder']] = df.loc[:, 'Debris Crew WO#'].str[26:]
df.loc[:, ['Place Holder']] = df.loc[:, ['Place Holder']].str.split().join(" ")
#plus its still hard coding (gross)
 

Далее я собираюсь поработать с РЕ. Мне сказали, что он отлично подходит для стиля «Поиск по CTRL», такого как тип фильтрации, и является ключевым инструментом в науке о данных. Итак, спускаемся в эту кроличью нору на следующую неделю начинаем с повторной документации и практикуемся в этой проблеме. Будет редактироваться с обновлениями по мере моего продвижения

Тем не менее. Я изучаю python уже почти два месяца. Пожалуйста, простите любые стили/кодирование «noob», которые просто пытаются и экспериментируют, чтобы я мог сделать свою жизнь и других людей вокруг меня намного лучше. Любая помощь будет оценена по достоинству. Заранее спасибо

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

1. Экипажа №405 в вашем списке нет. и экипаж #803 отформатирован по-другому, как # 803 вместо #803? Это опечатки?

2. Да, я привел только короткий фрагмент, но все в этом списке на самом деле находится в более широком фрейме данных. существует около 2500 строк с подобной информацией, и этот список-это команды, которые мне нужно проверить на данный момент. При необходимости я добавлю/выну из этого списка по мере необходимости

Ответ №1:

Способ № 1 со ссылкой на список:

Вы можете использовать str.extract() группу захвата в качестве объединенного списка join('|') . | Символ предназначен для ИЛИ и позволяет выполнять поиск нескольких значений одновременно для каждой строки. Для групп захвата требуются круглые скобки вокруг них, поэтому я добавляю круглые скобки в виде строк до и после.

 active_crews = ["CREW #101", "CREW #102", "CREW #203", "CREW #301", "CREW #404", "CREW #501", 
                "CREW #406", "CREW #304", "CREW #701", "CREW #702", "CREW #703", "CREW #704", 
                "CREW #705", "CREW #706", "CREW #707" "CREW #708", "CREW #801", "CREW #802", 
                "CREW #803", "CREW #805"]

df['Debris Crew WO#'] = df['Debris Crew WO#'].str.extract('('   '|'.join(active_crews)   ')')
df

#You  can also use a formatted string like this:
df['Debris Crew WO#'] = df['Debris Crew WO#'].str.extract(f'({"|".join(active_crews)})')

Out[1]: 
  Debris Crew WO#
0             NaN
1       CREW #406
2             NaN
 

Метод № 2 Извлечение на основе шаблона регулярного выражения и игнорирование списка. A ? после пробела означает, что пробел необязателен. Вместо a space вы также можете сделать s или s для нескольких пробелов. d означает последовательные числа. Если в числах есть запятые, регулярное выражение немного отличается:

 df['Debris Crew WO#'] = df['Debris Crew WO#'].str.extract('(CREW ?# ?d )')

Out[2]: 
  Debris Crew WO#
0            #405
1            #406
2           # 803
 

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

1. ВАУ, это было быстро, и это сработало. Это исключило экипаж, но кого это волнует на самом деле. Это не для презентации, а для того, чтобы я мог сгруппировать() этот номер экипажа. Мне всегда кажется, что в данный момент я слишком много думаю об этих вещах. Спасибо, что помогли мне. и я прямо сейчас пойду в туалет за выпиской документации.

2. @JQTS он не включил команду из-за места. Также смотрите мой другой вариант, чтобы вам не нужно было вручную обновлять список, если ваша цель-просто собрать все команды.

3. да! Просто для меня он выглядит гораздо более «чистым». Я еще совсем этого не понимаю, еще не начал читать документацию, но снова вау. Теперь у меня есть пример для практики дома после работы. Ты-бомба . ком !

4. str.extract , str.replace , str.findall , некоторые популярные векторизованные методы, в которых вы можете использовать регулярные выражения. Для некоторых из них вам, возможно, потребуется добавить флаг regex=True .