Pandas - группировка по регулярному выражению в зависимости от значения каждой строки - PullRequest
0 голосов
/ 14 июля 2020

Я уже проверял это Как перебирать строки в DataFrame в Pandas, но он не отвечает на мой вопрос

У меня pandas фрейм данных, содержащий 3 столбца: path, tags и column1, где tags - это list of strings, а column1 имеет boolean значений. Теперь я хочу сгруппировать их по path, используя регулярное выражение, которое частично зависит от значения path строки. А именно, каждая строка имеет уникальное значение, и я хочу сгруппировать их с другими файлами, которые содержат похожие path. Затем, если все строки в этой группе соответствуют некоторому условию (в этом примере таких элементов не может быть больше 5), столбцы всех строк изменяются.

def has_to_change(df):
  if len(df) > 5:
      return True
  else:
      False

def add_tag_to_tags(row):
  if 'tag' not in row['tags']:
      row['tags'].append('tag')
  return row

if __name__ == '__main__':

  pattern =  r'some regex'
  regex =  re.compile(pattern)

  df = pd.read_csv(df_path)

  for index, row in df.iterrows():
      file_name = row['path']
      matches = regex.search(file_name)
      org_path = matches.group('some regex group') #get a match from this row's path

      matching_rows = df[df['path'].str.contains(org_path+'(\.xml|\.txt)')] #find all rows that contain this file name but with some difference, say, another extentions xml or txt

      if has_to_change(matching_rows): #if condition met, change it's vale and save back to dataframe
          #i keep loop here because i want to overwrite row with the same index (it was originally a bit more complex)
          for inner_index, augmented_row in matching_rows.iterrows():
              augmented_row['column'] = True
              augmented_row.apply(add_tag_to_tags, axis=1)
              df.iloc[inner_index] = augmented_row

Может ли такое код как-нибудь векторизовать ? Это очень медленно, но я не могу найти способ:

  1. создавать группы по регулярному выражению
  2. проверять значение для каждой такой группы в целом
  3. и только затем обновите эти группы

Пример данных

      path,                              tags,             column1
/mnt/000000386703_aug_13237_0.jpg,       ['tag1'],         False
/mnt/000000386703_aug_13237_0.xml,       ['tag1'],         False
/mnt/000000386703_aug_13237_0.txt,       ['tag1', 'tag1'], False
/mnt/train_image_png_1221_aug_1245_5.jpg,['tag1'],         False
/mnt/000000306488_aug_9203_1.jpg,        ['tag1'],         False
/mnt/000000391768_aug_20250_1.jpg,       ['tag1'],         False
/mnt/1561887652.9493463_aug_1462_0.jpg,  ['tag1'],         True

После обновления:

      path,                              tags,                   column1
/mnt/000000386703_aug_13237_0.jpg,       ['tag1','tag'],         True
/mnt/000000386703_aug_13237_0.xml,       ['tag1','tag'],         True
/mnt/000000386703_aug_13237_0.txt,       ['tag1','tag1', 'tag'], True
/mnt/train_image_png_1221_aug_1245_5.jpg,['tag1'],               False
/mnt/000000306488_aug_9203_1.jpg,        ['tag1'],               False
/mnt/000000391768_aug_20250_1.jpg,       ['tag1'],               False
/mnt/1561887652.9493463_aug_1462_0.jpg,  ['tag1'],               True

Первые 3 строки имеют tag значение добавляется к tags столбцу, а значение столбца изменяется на True, потому что они разделяют path значение, которое улавливается регулярным выражением find all rows that have similar path (поэтому оно зависит от path строки)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...