#python #pandas #contains
Вопрос:
У меня есть набор данных, в котором я пытаюсь выбрать только строки, которые точно соответствуют определенным строкам в списке.
list = ['P:34.', 'R:ES.'] df = pd.DataFrame({ 'Date':['2021-01-01', '2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02', '2021-01-02', '2021-01-02', '2021-01-03'], 'Code':['P:34. R:ES.', 'R:ESB.', 'K2P:P:341.', 'R:ESZ', 'P:34.', 'R.ES7.', 'P 34 5', 'P:32. R:ES.'], 'Ratings':[9.0, 8.0, 5.0, 3.0, 2, 3, 6, 5]})
Я использовал функцию str.contains
для соответствующего выбора строк, но при этом я получаю строки, которые не соответствуют строкам в точности.
sample = df[df.Code.str.contains('|'.join(list),na=False)]
Я пытаюсь получить только строки, которые содержат именно строки (также учитывая точку в конце строк) в списке, который был бы примерно таким:
df_exact_match = pd.DataFrame({ 'Date':['2021-01-01', '2021-01-02', '2021-01-03'], 'Code':['P:34. R:ES.', 'P:34.', 'P:32. R:ES.'], 'Ratings':[9.0, 2, 5]})
Большое вам спасибо за ваш совет 🙂
Ответ №1:
Я получаю строки с не совсем совпадающими строками.
Это происходит потому, что по умолчанию Series.str.contains
предполагается, что первый аргумент является шаблоном регулярного выражения, а в регулярном выражении точка .
соответствует любому отдельному символу. Чтобы соответствовать буквальному .
, вы должны избежать его (т. Е. .
). Нет необходимости указывать na=False
кстати.
gt;gt;gt; l = ['P:34.', 'R:ES.'] gt;gt;gt; df[df.Code.str.contains('|'.join(l))] Date Code Ratings 0 2021-01-01 P:34. R:ES. 9.0 4 2021-01-02 P:34. 2.0 7 2021-01-03 P:32. R:ES. 5.0
Ответ №2:
Вы можете немного скорректировать свой код. Я бы сначала разделил столбец «Код», а затем использовал isin
в сочетании с any(axis=1)
, что позволило бы включить любые значения этого списка в ваш разделенный столбец «Код», который разбит на части:
l = ['P:34.', 'R:ES.'] df.loc[df['Code'].str.split(expand=True).isin(l).any(1)]
С принтами:
Date Code Ratings 0 2021-01-01 P:34. R:ES. 9.0 4 2021-01-02 P:34. 2.0 7 2021-01-03 P:32. R:ES. 5.0
Также не рекомендуется называть свой обычай list
, список. Лучше использовать другое имя. Я бы также посоветовал не использовать str.contains
, так как это вернет частичные совпадения, как следует из названия, а не точные совпадения.
Комментарии:
1. Большое спасибо за ваш ответ, он отлично работает. Вы также знаете, будет ли также возможность сделать это с помощью str.contains() и регулярного выражения?
2. Круто, добро пожаловать.
regex
нужен шаблон для распознавания. Есть ли закономерность в значениях, которые вы фильтруете?3. Да, все строки, которые я пытаюсь отфильтровать в своем фрейме данных, начинаются с «R:» 2-4 буквы и заканчиваются точкой. Например [‘R:СШИТЬ.’, ‘R:FK.’, ‘R:WOLH.’]