Это связано с вопросом, который я задавал ранее, я публикую этот новый, так как считаю его достаточно уникальный и постоянно сложным. У меня есть фрейм данных вида:
keyword string match
A "Varied String..." ['string','string','test','string']
"Varied String..." ['string','string']
"Varied String..." ['test']
B "Varied String..." ['string,'string','test']
Который был создан с помощью этого кода (который был написан @anky_91):
df1.groupby(df2.Type.ffill()).matches.apply(lambda x: ''.join(mode(list(chain.from_iterable(x)))[0]))
Моя проблема на данный момент заключается в том, что это создает новые совпадения столбцов, что совершенно нормально, однако, хотя мне нужен режим, мне нужно только наиболее частое уникальное значение. Поэтому вместо того, чтобы столбец match
заполнялся режимом списка, я пытаюсь сделать его просто наиболее частым значением режима, поэтому:
keyword string match
A "Varied String..." 'string'
B "Varied String..." 'string'
Я пытался сделать это:
df = freq_df['matches'].agg(lambda x: x.value_counts().index[0])
Что возвращается, то же самое без изменений. Я тогда пытаюсь,
df['matches'].value_counts()
Который возвращает неточные значения, поэтому я не уверен, что с этим происходит.
Дайте мне знать, если это ясно или нет!
Я думаю, вы хотите использовать применить вместо gg
@Will df1 — это фрейм данных без столбца matches
, а df2 — это добавленный к нему столбец matches
, столбец matches
был получен из столбца string
в df1, где каждая строка представляет собой предложение, содержащее определенные ключевые слова (в данном случае "string","test"
), это помогает?
@iamchoosinganame Я пробовал, но получаю AttributeError: 'list' object has no attribute 'value_counts'
Это потому, что значение представляет собой список, а не серию. Вы можете преобразовать его в серию. df = freq_df['matches'].apply(lambda x: pd.Series(x).value_counts().index[0])
@iamchoosinganame остается без изменений :(
Вместо того, чтобы использовать Series.str.findall() для извлечения совпадений в списки, вы можете использовать Series.str.extractall() для извлечения каждого совпадающего слова в свою собственную строку, что может упростить вашу задачу (ниже используются ваши образцы данных в предыдущем посте и удалены двойные кавычки из столбца нить).
# list of keywords
keyword_list=['string', 'test']
# regex pettern to retrieve only words matched from keywork_list
ptn = r'\b(' + '|'.join(keyword_list) + r')\b'
# get the list of matched words (assume `keyword` is already on index), if not, use the following
# s = df.set_index('keyword').string.str.extractall(ptn).reset_index(level=1, drop=True)[0]
s = df.string.str.extractall(ptn).reset_index(level=1, drop=True)[0]
print(s)
#keyword
#A test
#A string
#A test
#A string
#A string
#A string
#A test
#A string
#B test
#B string
#B test
#B string
#B test
#Name: 0, dtype: object
Затем вы можете получить верхний элемент с помощью value_counts() для каждого ключевого слова.
s.groupby('keyword').apply(lambda x: x.value_counts().nlargest(1))
#keyword
#A string 5
#B test 3
#Name: 0, dtype: int64
или просто ключевое слово и строка без счета:
s.groupby('keyword').apply(lambda x: x.value_counts().idxmax())
#keyword
#A string
#B test
#Name: 0, dtype: object
Извините за поздний ответ, только что вернулся в офис. Это потрясающе! Единственное, что мне нужно выяснить на данный момент, это как назначить строку с самой высокой частотой для определенного ключевого слова, поскольку сейчас она все еще отображает несколько частот для каждого ключевого слова.
@SebastianGoslin, не знаю, правильно ли я вас понял, я думаю, вы, вероятно, просто пропустили один шаг, чтобы назначить результат новому фрейму данных: df_new = s.groupby('keyword').apply(lambda x: x.value_counts().idxmax()).to_frame('most_freq_string')
Аааа получилось! Если бы я мог выбрать ваш мозг еще для одной вещи, он по-прежнему возвращает несколько значений для A
, поскольку фрейм данных имеет длинный формат, поэтому «A» равно множеству разных строк, есть ли способ объединить все различные значения для A
и присвоить ему одно ? На данный момент он назначает наиболее частое ключевое слово в этой строке, а не все вхождения A
. Имеет ли это смысл, пожалуйста, скажите мне, если это не так!
Неважно, я нашел способ! df.pivot_table(index='keyword', values='most_freq_string', aggfunc=lambda x: ' '.join(str(v) for v in x))
Что такое дф1 и дф2?