После маркирования столбца получите 2 слова до и после определенного слова

#python #pandas #dataframe

Вопрос:

Я только что обозначил столбец в фрейме данных с помощью nltk.word_tokenize. Эта колонка теперь выглядит так

 df.tokenized
> 0     [apple, hi, dog, boy, why...]
> 1     [table, hey, girl, cat, dog, 2, 3...
 

Для каждой строки мне нужно получить 2 слова до и 2 слова после слова «собака». Я хочу поместить все это в другой столбец в том же фрейме данных. Результат, который я ожидаю, будет примерно таким:

 df.tokenized_part2
> 0     [apple, hi, dog, boy, why]
> 1     [girl, cat, dog, 2, 3]
 

Поэтому мне нужно создать этот столбец с маркировкой _part2.

Если вам нужна эта информация: маркированный объект

Кто-нибудь знает, как это сделать?

Комментарии:

1. может быть, вам следует повторить каждую строку и найти позицию в строке, а затем получить [pos-2:pos 2]

2. что делать, если в списке нет собаки?

Ответ №1:

Вы можете использовать apply() функцию для запуска в каждой ячейке столбца, и эта функция может получить позицию dog в списке и вернуться [pos-2:pos 3]

 import pandas as pd

df = pd.DataFrame({
"tokenized": [
    ['apple', 'hi', 'dog', 'boy', 'why', 'other'],
    ['table', 'hey', 'girl', 'cat', 'dog', '2', '3'],
    ['A', 'B', 'C'],
]
})

def process(words):
    #print(words)
    if 'dog' in words:
        pos = words.index('dog')
        return words[pos-2:pos 3]
    else:
        #return words
        return []

df["tokenized_2"] = df["tokenized"].apply(process)

print(df)
 

Результат:

                             tokenized                 tokenized_2
0   [apple, hi, dog, boy, why, other]  [apple, hi, dog, boy, why]
1  [table, hey, girl, cat, dog, 2, 3]      [girl, cat, dog, 2, 3]
2                           [A, B, C]                          []
 

Редактировать:

Чтобы сделать его более универсальным, он мог бы получить dog (или другое слово) в качестве параметра, а затем вы бы запустили его с lambda (или partial )

 import pandas as pd

df = pd.DataFrame({
"tokenized": [
    ['apple', 'hi', 'dog', 'boy', 'why', 'other'],
    ['table', 'hey', 'girl', 'cat', 'dog', '2', '3'],
    ['A', 'B', 'C'],
]
})

def process(words, search):
    #print(words)
    if search in words:
        pos = words.index(search)
        return words[pos-2:pos 3]
    else:
        #return words
        return []

df["tokenized_dog"] = df["tokenized"].apply(lambda words:process(words, 'dog'))
df["tokenized_cat"] = df["tokenized"].apply(lambda words:process(words, 'cat'))

print(df[["tokenized_dog", "tokenized_cat"]])
 

Результат:

                 tokenized_dog             tokenized_cat
0  [apple, hi, dog, boy, why]                        []
1      [girl, cat, dog, 2, 3]  [hey, girl, cat, dog, 2]
2                          []                        []
 

Комментарии:

1. Идеально! Чтобы сделать его еще более универсальным: list_words = [‘кошка’, ‘собака’, ‘птица’] для элемента в list_words: df[‘col’ ‘_’ str(элемент)] = df[«маркированный»].применить(лямбда-слова:процесс(слова, элемент))

Ответ №2:

Один из способов сделать это-использовать apply с lambda, например

 lambda x: [i for ix,i in enumerate(x) if ix in range([idx for idx,it in x if it=='dog'][0]-2,[idx for idx,it in x if it=='dog'][0] 2)]
 

Но это дорого с точки зрения вычислений, подвержено ошибкам и, вероятно, излишне сложно.

Комментарии:

1. это совершенно нечитабельно или понятно

2. @gold_cy это буквально process из другого ответа как понимание вложенного списка внутри лямбды. Или, скорее, поскольку они ответили после меня, их функция-понимание моего вложенного списка, растянутого на ненужное количество символов. Если кому-то нужно объяснить вам, что заполнители в понятиях (например, циклах) и лямбда-выражениях (например, функциях) не обязательно должны быть значимыми, чтобы быть понятными, вам следует подумать о том, где корень этой проблемы. Им нужен был рабочий код. Код работает.

3. жертвовать строками кода, чтобы сделать его читабельным, всегда считается правильным подходом. дополнительные строки кода не означают дополнительной обработки. в таком языке, как Python, читабельность имеет первостепенное значение и то, что она превосходит ее.

4. О. Я думал, что это удивительный ассортимент библиотек, динамическая типизация и способность невероятно эффективно решать проблемы в коде вместо того, чтобы набирать множество и множество для простых задач.

5. Кстати, теперь я собираюсь понять ваш первый комментарий программно, а не в смысле естественного языка. Спасибо, что сказали, что мой код понятен @gold_cy.