Количество дубликатов списка в фрейме данных Pandas по группам

#python #pandas #data-science

#python #pandas #наука о данных

Вопрос:

У меня есть фрейм данных, который в настоящее время выглядит следующим образом:

 image         source                               label
bookshelf     A                      [flora, jar, plant]
bookshelf     B                    [indoor, shelf, wall]
bookshelf     C             [furniture, shelf, shelving]
cactus        A                     [flora, plant, vine]
cactus        B                [building, outdoor, tree]
cactus        C                  [home, house, property]
cars          A          [parking, parking lot, vehicle]
cars          B                     [car, outdoor, tree]
cars          C            [car, motor vehicle, vehicle]
  

Что я хотел бы получить, так это количество дубликатов label для каждого source на image , т.Е.:

  1. для image книжной полки источники B и C имеют общую метку «полка» (B = 1; C = 1)
  2. для image cactus ни в одном источнике нет одинаковых меток
  3. для image автомобилей источники B и C имеют общую метку «автомобиль» (B = 1; C = 1), а источники A и C имеют общую метку «транспортное средство» (A = 1; C = 1)

Объектом ответа будет количество раз, когда источники совместно используют метки. В приведенном выше примере (1) увеличило бы количество B и C на 1 каждый, и (3) увеличило бы количество B и C на 1 каждый, а количество A и C на 1 каждый:

 { 'A': 1, 'B': 2, 'C': 3 }
  

Воспроизводимый пример:

 from pandas import DataFrame
df = DataFrame({
  'image': ['bookshelf', 'bookshelf', 'bookshelf',
            'cactus', 'cactus', 'cactus',
            'cars', 'cars', 'cars'],
  'source': ['A', 'B', 'C',
             'A', 'B', 'C',
             'A', 'B', 'C'],
  'label': [
    ['flora', 'jar', 'plant'],
    ['indoor', 'shelf', 'wall'],
    ['furniture', 'shelf', 'shelving'],
    ['flora', 'plant', 'vine'],
    ['building', 'outdoor', 'tree'],
    ['home', 'house', 'property'],
    ['parking', 'parking lot', 'vehicle'],
    ['car', 'outdoor', 'tree'],
    ['car', 'motor vehicle', 'vehicle']]
  },
  columns = ['image', 'source', 'label']
)
  

Хотя обычно на источник / изображение приходится 3 метки, это не гарантируется.

Есть идеи о том, как я мог бы достичь этого с хорошей производительностью? У меня есть несколько миллионов записей для обработки подобным образом…

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

1. Как label представлено? Строки? Списки?

2. label это список строк

3. Не могли бы вы добавить код для генерации данных?

Ответ №1:

Это должно выполнить задание:

 from collections import Counter
sources = df['source'].unique()
output = {source: 0 for source in sources}
for image, sub_df in df.groupby('image'):
    counts = Counter(sub_df['label'].sum())
    for image, source, labels in sub_df.itertuples(index=False):
        for label in labels:
            output[source]  = counts[label] - 1
print(output)
  

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

1. Краткое и приятное отображение Counter и itertuples