Выполните итерацию по двум столбцам, чтобы увидеть, присутствует ли подстрока в списке, добавьте ее в третий столбец

#python #regex #pandas #dataframe

#python #регулярное выражение #pandas #фрейм данных

Вопрос:

У меня есть список строк:

 YOUTUBE = ['bumper youtube','yt trueview', 'youtube trueview','yt pre-roll','youtube pre-roll','yt bumper','youtube bumper' ,'bumper','yt preferred pre-roll','youtube preferred pre-roll', 'YT preferred bumper', 'youtube preferred bumper', 'YT masthead', 'youtube masthead', 'trueview youtube','trueview']
  

У меня также есть фрейм данных pandas, подобный этому:

 Line Item                                      |    Insertion Order            | Creative Size           
_____________________________________________________________________
ch video cross ff bumper youtube mk it mb      | gen 20 youtube                | Unknown    
moisturizerbody trueview ym21998557 yt youtube | trueview ym21998557 yt youtube| Unknown
useless string                                 | dunno                         | Unknown
012020 trueview ym21978191 yt youtube bumper   | davena bumper youtube 24      | Unknown
  

Я должен выполнить итерацию как по порядку вставки столбцов, так и по размеру креатива.
Если какое-либо значение в списке YOUTUBE находится в строке столбца или порядке вставки, строка, которая находится в списке, должна быть вставлена в размере креатива в соответствующей строке. Если существует более одного возможного совпадения, любая совпадающая строка в порядке.
Как я могу это сделать? При необходимости можно импортировать регулярное выражение

Ответ №1:

Используйте Series.str.findall with для объединения обеих строк столбцов с помощью with bb для границ слов:

 pat = '|'.join(r"b{}b".format(x) for x in YOUTUBE)
df['new'] = (df['Line Item']   ' '   df['Insertion Order']).str.findall(pat).str.join(', ')

print (df)
                                        Line Item  
0       ch video cross ff bumper youtube mk it mb   
1  moisturizerbody trueview ym21998557 yt youtube   
2                                  useless string   
3    012020 trueview ym21978191 yt youtube bumper   

                  Insertion Order Creative Size                         new  
0                  gen 20 youtube       Unknown            [bumper youtube]  
1  trueview ym21998557 yt youtube       Unknown                  [trueview]  
2                           dunno       Unknown                          []  
3        davena bumper youtube 24       Unknown  [trueview, bumper youtube]  
  

Если nees объединил строки с помощью , add Series.str.join :

 pat = '|'.join(r"b{}b".format(x) for x in YOUTUBE)
df['new'] = df['Line Item'].add(df['Insertion Order']).str.findall(pat).str.join(', ')

print (df)
                                        Line Item  
0       ch video cross ff bumper youtube mk it mb   
1  moisturizerbody trueview ym21998557 yt youtube   
2                                  useless string   
3    012020 trueview ym21978191 yt youtube bumper   

                  Insertion Order Creative Size                       new  
0                  gen 20 youtube       Unknown            bumper youtube  
1  trueview ym21998557 yt youtube       Unknown                  trueview  
2                           dunno       Unknown                            
3        davena bumper youtube 24       Unknown  trueview, bumper youtube  
  

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

1. По какой-то причине это не работает, может быть связано с SettingWithCopyWarning: значение пытается быть установлено для копии фрагмента из фрейма данных. Попробуйте вместо этого использовать .loc[row_indexer,col_indexer] = value ?

2. Каков ваш полный код? Возможно ли редактировать вопрос?

Ответ №2:

Вы можете найти индекс, в котором есть совпадение, и скопировать это совпадение в интересующий столбец, как в этом примере:

 data = pd.DataFrame({"Line Item": ['nope', 'nope', 'yep1!'],"Insertion Order": ['nope', 'yep2!', 'nope'], "Creative Size": ['', '', '']})
youtube = ['foo', 'bar', 'yep1!', 'yep2!']

for col in data.columns:
    ind = data.loc[data[col].isin(youtube)].index
    data['Creative Size'].iloc[ind] = data[col].iloc[ind]

data
  

вывод:
введите описание изображения здесь

Ответ №3:

Эта реализация проста и должна работать. Последнее совпадение (в столбцах «Строка» или «Порядок вставки») переопределит все предыдущие совпадения (в этих 2 столбцах), и эта строка — это строка, которую вы увидите в столбце «Размер креатива» для каждой строки. df_ex — это имя фрейма данных примера.

 for idx,row in df_ex.iterrows():
    for string in YOUTUBE:
        if (string in row['Line Item']) or (string in row['Insertion Order']): # can also use regex here
            df_ex.loc[idx, 'Creative Size'] = string
  

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

1. Добро пожаловать в Stack Overflow. Возможно, вы захотите улучшить свой ответ, добавив краткое объяснение важной части. Для будущих читателей гораздо интереснее увидеть объяснение, почему это отвечает на вопрос.