Я уже проверял это Как перебирать строки в 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
Может ли такое код как-нибудь векторизовать ? Это очень медленно, но я не могу найти способ:
- создавать группы по регулярному выражению
- проверять значение для каждой такой группы в целом
- и только затем обновите эти группы
Пример данных
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
строки)