Я относительный новичок в Python, а также новичок в обработке естественного языка (NLP).
У меня есть фрейм данных, содержащий имена и продажи. Я хочу: 1) выделить все токены и 2) объединить продажи по каждому токену.
Вот пример фрейма данных:
name sales
Mike Smith 5
Mike Jones 3
Mary Jane 4
Вот желаемый результат:
token sales
mike 8
mary 4
Smith 5
Jones 3
Jane 4
Мысли, что делать? Я использую Python.
На самом деле, это не всегда будет имя и фамилия. Существует бесконечное количество токенов, поэтому код должен динамически обрабатывать различное количество токенов. и спасибо за помощь.
Вы можете использовать метод str.split()
и сохранить элемент 0
для имени, используя его в качестве группового ключа и взять сумму, затем сделать то же самое для элемента -1
(фамилия) и объединить их.
import pandas as pd
df = pd.DataFrame({'name': {0: 'Mike Smith', 1: 'Mike Jones', 2: 'Mary Jane'},
'sales': {0: 5, 1: 3, 2: 4}})
df = pd.concat([df.groupby(df.name.str.split().str[0]).sum(),
df.groupby(df.name.str.split().str[-1]).sum()]).reset_index()
df.rename(columns = {'name':'token'}, inplace=True)
df[["fname", "lname"]] = df["name"].str.split(expand=True) # getting tokens,considering separated by space
tokens_df = pd.concat([df[['fname', 'sales']].rename(columns = {'fname': 'tokens'}),
df[['lname', 'sales']].rename(columns = {'lname': 'tokens'})])
pd.DataFrame(tokens_df.groupby('tokens')['sales'].apply(sum), columns=['sales'])
Предположение: у вас есть функция tokenize
, которая принимает строку в качестве входных данных и возвращает список токенов.
Сейчас я буду использовать эту функцию в качестве токенизатора:
def tokenize(word):
return word.casefold().split()
Решение
df.assign(tokens=df['name'].apply(tokenize)).explode('tokens').groupby('tokens')['sales'].sum().reset_index()
In [45]: df
Out[45]:
name sales
0 Mike Smith 5
1 Mike Jones 3
2 Mary Jane 4
3 Mary Anne Jane 1
In [46]: df.assign(tokens=df['name'].apply(tokenize)).explode('tokens').groupby('tokens')['sales'].sum().reset_index()
Out[46]:
tokens sales
0 anne 1
1 jane 5
2 jones 3
3 mary 5
4 mike 8
5 smith 5
Объяснение
tokens
, который применяет функцию tokenize
Примечание. Для этой конкретной функции tokenize
вы можете использовать df['name'].str.lower().str.split()
, однако это не будет распространяться на пользовательские токенизаторы, поэтому .apply(tokenize)
это генерирует df, который выглядит как
name sales tokens
0 Mike Smith 5 [mike, smith]
1 Mike Jones 3 [mike, jones]
2 Mary Jane 4 [mary, jane]
3 Mary Anne Jane 1 [mary, anne, jane]
df.explode
на этом, чтобы получить name sales tokens
0 Mike Smith 5 mike
0 Mike Smith 5 smith
1 Mike Jones 3 mike
1 Mike Jones 3 jones
2 Mary Jane 4 mary
2 Mary Jane 4 jane
3 Mary Anne Jane 1 mary
3 Mary Anne Jane 1 anne
3 Mary Anne Jane 1 jane
Спасибо. Можете ли вы разместить весь код в одном месте? Мне трудно понять примеры кода, когда они разбиты.
это там в первой половине: df.assign(tokens=df['name'].apply(tokenize)).explode('tokens').groupby('tokens')['sales'].sum().reset_index()
Спасибо. Я не понимаю, куда идет функция tokenize.
tokenize
— это просто функция-заполнитель, которая принимает строку и возвращает список токенов. Я использовал очень простой, который просто строчные буквы и разбивается на пробелы. Есть много других токенизаторов слов. nltk
имеет word_tokenize
например.
У вас уже есть любимый токенизатор? Будут ли имена всегда
firstname lastname
?