#python #pandas #dataframe
#python #pandas #фрейм данных
Вопрос:
У меня есть два фрейма данных.
Первый df состоит из записей со списком терминов, классифицирующих каждую запись, и столбца «Отрасль», для которого я пытаюсь присвоить значения.
df1 = pd.DataFrame([['a', ['Elementary', 'Pre Schools', 'High Schools'], None], ['b', ['Museums'], None], ['c', ['Junior High Schools', 'Military - Misc.', 'Roads', 'Sewers and Water Mains'], None]], columns=['Record Name', 'Terms', 'Industry'])
df1 выглядит так
Record Name Terms Industry
0 a [Elementary, Pre Schools, High Schools] None
1 b [Museums] None
2 c [Junior High Schools, Military - Misc., Roads, Sewers and Water Mains] None
Второй df предоставляет списки терминов и их соответствующую «отрасль».
df2 = pd.DataFrame([['Arts', ['Libraries', 'Museums', 'Auditoriums', 'Entertainment']], ['Education', ['Elementary', 'Pre Schools', 'College', 'University', 'Junior High Schools', 'High Schools']]])
d2 выглядит так
Industry Terms
0 Arts [Libraries, Museums, Auditoriums, Entertainment]
1 Education [Elementary, Pre Schools, College, University, Junior High Schools, High Schools]
df2 содержит 10 различных отраслей с примерно 100 терминами, распределенными по ним. Не каждый термин, присутствующий в df1, используется для классификации отрасли в df2.
Как бы я назначил «отраслевые» значения в df1 на основе любых общих элементов списка «терминов» между df1 и df2? Вот желаемый результат:
Record Name Terms Industry
0 a [Elementary, Pre Schools, High Schools] Education
1 b [Museums] Arts
2 c [Junior High Schools, Military - Misc., Roads, Sewers and Water Mains] Education
Я попытался просто использовать серию списков для каждой отрасли и соответствующих ей терминов, чтобы я мог назначить с помощью .isin()
df1.loc[df1['Terms'].isin(Education), 'Industry'] = 'Education'
Но это присваивает «Отрасль» только для записей, все их «термины» присутствуют в списке образования. Кроме того, поскольку существует 10 различных отраслей, определение списков и создание отдельных назначений для каждого из них было бы громоздким. Я считаю, что оценка общих «терминов» между двумя фреймами данных была бы более чистым подходом.
Комментарии:
1. В вашем столбце df1 есть несколько элементов
Terms
. Какому из них оно должно соответствовать?2. Любой df1 [‘Terms’], общий для df2 [‘Terms’], должен быть сопоставлен.
Ответ №1:
Мне сложно работать со списками в фреймах данных, поэтому я сначала разбиваю списки, затем объединяю фреймы данных и собираю списки вместе.
#This just helps me keep the columns straight
df2.columns = ['Industry', 'Terms']
# Drop Industry in df1 and explode the lists in df1 amp; df2
df1 = df1.drop('Industry', axis=1).explode('Terms')
df2 = df2.explode('Terms')
# Merge the terms back into df1
df1 = df1.merge(df2, how='left', on='Terms')
# Bring the lists back together
df1 = df1.groupby('Record Name').agg(lambda x: x.dropna().unique().tolist())
Результат:
Terms Industry
Record Name
a [Elementary, Pre Schools, High Schools] [Education]
b [Museums] [Arts]
c [Junior High Schools, Military - Misc., Roads,... [Education]