#python #pandas #dataframe #group-by #data-analysis
#питон #панды #фрейм данных #группа-по #анализ данных
Вопрос:
У меня есть df со следующей структурой
vid sid pid url 1 A A1 page ABCDEF 2 A A1 page DEF123 3 A A1 page GHI345 4 A A1 page JKL345 5 B B1 page AB12345EF 6 B B2 page IJK 7 B B2 page XYZ 8 C C1 page ABCEF dict = {'vid':{1:'A',2:'A',3:'A',4:'A',5:'B',6:'B',7:'B',8:'C'}, 'sid':{1:'A1',2:'A1',3:'A1',4:'A1',5:'B1',6:'B2',7:'B2',8:'C1'}, 'page':{1:'page',2:'page',3:'page',4:'page',5:'page',6:'page',7:'page',8:'pge'}, 'url':{1:'ABC',2:'DEF',3:'GHI',4:'JKL',5:'ABC',6:'IJK',7:'XYZ',8:'ABC'} }
У меня также есть список подстрок
lst = ['AB','EF']
По сути, я хочу сгруппироваться sid
и проверить каждую строку url
. Если все элементы в списке существуют в виде подстроки хотя бы в одной строке, то верните значение sid
.Если нет, отфильтруйте sid
из df. Подстроки внутри url
не являются последовательными.
Psuedo-код
group by sid if row in url contains all the substrings in lst pass if no row in url contains all substrings in lst remove the `sid` from the df
Результат применения приведенной выше логики к df с использованием lst
enter code here vid sid pid url 1 A A1 page ABCDEF 2 A A1 page DEF123 3 A A1 page GHI345 4 A A1 page JKL345 5 B B1 page AB12345EF 8 C C1 page ABCEF
Комментарии:
1.
df[df.url.apply(lambda s: any([x in s for x in lst])).groupby(df.sid).transform(any)]
2. обратите внимание, что общий словарь отличается от таблицы
Ответ №1:
Получите логическую маску для URL в lst
:
# `all` check for rows that have both `AB` and `EF` mask = [all(a in ent for a in lst) for ent in df.url] mask = pd.Series(mask, index = df.index) # Group mask with `Sid` and filter `df`: df.loc[mask.groupby(df.sid).transform('any')] vid sid pid url 1 A A1 page ABCDEF 2 A A1 page DEF123 3 A A1 page GHI345 4 A A1 page JKL345 5 B B1 page AB12345EF 8 C C1 page ABCEF
Комментарии:
1. Я пытаюсь реализовать это, но я думаю, что он возвращает идентификаторы sid, в которых в столбце существует один элемент списка
url
. Я искал только SID, где все элементы списка существуют как минимум в 1 строке.2. приятное наблюдение @Sebazz44; обновил код. посмотрите, охватывает ли он ваш вариант использования или все еще имеет утечку в логике
3. на самом деле я решил эту проблему, переключив оператор трубы регулярного выражения на
AND
эквивалент, но ваше решение приблизило меня достаточно близко 🙂 спасибо!
Ответ №2:
Используйте логическую индексацию:
import pandas as pd gb_df = df.groupby('sid')['url'].transform(lambda x : [x.tolist()]*len(x)) indexing = gb_df.apply(lambda li: any(any(el in text for text in li) for el in lst)) output = df[indexing]
Выход:
vid sid pid url 1 A A1 page ABCDEF 2 A A1 page DEF123 3 A A1 page GHI345 4 A A1 page JKL345 5 B B1 page AB12345EF 8 C C1 page ABCEF