#python #list #dataframe #apply #spacy
Вопрос:
У меня есть столбец (довольно) длинных текстов во фрейме данных, и для каждого текста есть список индексов предложений, которые я хотел бы удалить. Индексы предложений были сгенерированы Spacy, когда я разбивал тексты на предложения. Пожалуйста, рассмотрите следующий пример:
import pandas as pd
import spacy
nlp = spacy.load('en_core_web_sm')
data = {'text': ['I am A. I am 30 years old. I live in NY.','I am B. I am 25 years old. I live in SD.','I am C. I am 30 years old. I live in TX.'], 'todel': [[1, 2], [1], [1, 2]]}
df = pd.DataFrame(data)
def get_sentences(text):
text_clean = nlp(text)
sentences = text_clean.sents
sents_list = []
for sentence in sentences:
sents_list.append(str(sentence))
return sents_list
df['text'] = df['text'].apply(get_sentences)
print(df)
что дает следующее:
text todel
0 [I am A., I am 30 years old., I live in NY.] [1, 2]
1 [I am B. I am 25 years old., I live in SD.] [1]
2 [I am C. I am 30 years old., I live in TX.] [1, 2]
Как бы вы эффективно удалили предложения, хранящиеся в todel
, зная, что у меня очень большой набор данных с более чем 50 предложениями, которые нужно удалить для каждой строки ?
Мой ожидаемый результат будет:
text todel
0 [I live in NY.] [1, 2]
1 [I am 25 years old., I live in SD.] [1]
2 [I live in TX.] [1, 2]
Комментарии:
1. каков ваш ожидаемый результат?
2. Я добавил это в своем вопросе
Ответ №1:
Попробуй это:
import pandas as pd
data = {'text': ['I am A. I am 30 years old. I live in NY.','I am B. I am 25 years old. I live in SD.','I am C. I am 30 years old. I live in TX.'], 'todel': [[1, 2], [1], [1, 2]]}
df = pd.DataFrame(data)
def fun(sen, lst):
return ('.'.join(s for idx, s in enumerate(sen.split('.')) if idx 1 not in lst))
df['text'] = df.apply(lambda row : fun(row['text'],row['todel']), axis=1)
Выход:
text todel
0 I live in NY. [1, 2]
1 I am 25 years old. I live in SD. [1]
2 I live in TX. [1, 2]
РЕДАКТИРОВАТЬ базу по отредактированному вопросу :
Если df['text']
список предложений вам не нужно разделять, и вы можете попробовать это:
data = {'text': [['I am A.', 'I am 30 years old.', 'I live in NY.'],
['I am B.', 'I am 25 years old.', 'I live in SD.'],
['I am C.','I am 30 years old.',' I live in TX.']], 'todel': [[1, 2], [1], [1, 2]]}
df = pd.DataFrame(data)
# text todel
# 0 [I am A., I am 30 years old., I live in NY.] [1, 2]
# 1 [I am B., I am 25 years old., I live in SD.] [1]
# 2 [I am C., I am 30 years old., I live in TX.] [1, 2]
def fun(sen, lst):
return [s for idx , s in enumerate(sen) if not idx 1 in lst]
df['text'] = df.apply(lambda row : fun(row['text'],row['todel']), axis=1)
print(df)
Выход:
text todel
0 [I live in NY.] [1, 2]
1 [I am 25 years old., I live in SD.] [1]
2 [ I live in TX.] [1, 2]
Комментарии:
1. Спасибо, очень признателен. Но вы уверены
sen.split('.')
, что разделяете предложение так же, как при использовании Spacy ?2. @krasnapolsky что такое spacy?
3. Я также не знаю спейси, но вы либо разделитесь с пробелом, либо без..
sen.split('. ')
уберете пробел, но тогда вам придется включить его в'. '.join(...)
4. Spacy-это пакет для обработки строк. Я упоминаю в своем посте, что с помощью этого пакета я получаю индекс предложений для удаления. Поэтому мне нужно быть уверенным, что
sen.split('. ')
это дает ту же индексацию предложений, что и при использовании Spacy.5. @krasnapolsky ХОРОШО, я понимаю. дай мне секунду
Ответ №2:
Основываясь на ответе @user1740577:
def fun(sen, lst):
return [i for j, i in enumerate(sen) if j not in lst]
df['text'] = df.apply(lambda row : fun(row['text'],row['todel']), axis=1)
Дает желаемый результат, основанный на индексации Spacy:
text todel
0 [I am A.] [1, 2]
1 [I am B. I am 25 years old.] [1]
2 [I am C. I am 30 years old.] [1, 2]