Сгруппируйте по и верните все значения индекса, в которых в столбце имеется подстрока текста

#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