#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. Возможно, вы захотите улучшить свой ответ, добавив краткое объяснение важной части. Для будущих читателей гораздо интереснее увидеть объяснение, почему это отвечает на вопрос.