Найти вхождения строк в DataFrame по сравнению значения, полученного регулярным выражением

Рейтинг: 0Ответов: 1Опубликовано: 18.04.2023

Есть структура DataFrame, в которой хранится таблица с уязвимостями (много столбцов с различной информацией, такой как Идентификатор, Наименование, Версия ПО и т.д.).

Нужно отобрать определенные строки этой таблицы (вхождения по условиям). Например, значение столбца "Версия ПО" в конкретной строке -

"от 4.4.10 до 4.4.55 включительно (Linux), до 2.40.11 включительно (librsvg)".

Нужно вычленить значение версии, относящейся к (Linux), и сравнить её с конкретной (например с 4.4.54), а также запомнить это строку и записать её в новый DataFrame, если по результатам сравнения она проходит проверку (то есть наша версия 4.4.54 подвержена этой уязвимости).

Пока что смог реализовать поиск по простому вхождению конкретно описанного условия

vul_dataset = pd.read_excel(vul_base)

result_set = vul_dataset[
                    (vul_dataset['Версия ПО'].str.contains(r'(\d+.\d+.?\d+)\D+\(Linux\)', regex=True)
]

Но .str.contains возвращает True/False по простому соответствию, собственно вопрос - как добавить сравнение?

Ответы

▲ 1Принят

Здесь несколько вопросов. Первый - это достоверно выделить номера версий "от и до" из строк. Второй - сравнить выделенные версии с целевой.
Предложу в первом приближении вариант решения: с помощью .str.extract() выделяем в 2 столбца номера версий "от и до", которые превращаем в целые числа после удаления точек. Далее фильтруем df1 условием "версия больше или равна нижней границе и меньше или равна верхней границе", забираем индексы и отбираем нужные строки исходного фрейма.

df = pd.DataFrame({'Версия ПО': ['от 4.4.10 до 4.4.55 включительно (Linux), до 2.40.11 включительно (librsvg)',
                                 'от 4.4.10 до 4.4.40 включительно (Linux), до 2.40.11 включительно (librsvg)',
                                 'от 4.4.10 до 4.4.55 включительно (Unix), до 2.40.11 включительно (librsvg)']})
ver = '4.4.54'
ver = int(ver.replace('.',''))

df1 = df['Версия ПО'].str.extract(r'([\d.]+)\s+до\s+([\d.]+).+?Linux').replace('\.', '', regex=True).dropna().astype(int)
df1 = df1[df1[0].le(ver) & df1[1].ge(ver)]
print(df.loc[df1.index,'Версия ПО'])
0    от 4.4.10 до 4.4.55 включительно (Linux), до 2...
Name: Версия ПО, dtype: object