Я пытаюсь отфильтровать строки кадра данных, где столбец строк под именем «вопрос» содержит все подстроки в заданном списке. То есть, если данный список подстрок равен ['King', 'England']
, мне нужно сохранить все строки в фрейме данных, где строка в df.question
содержит как King
, так и England
.
Этот код выполняется без проблем и выводит логическое значение:
print(all([word in df.question[0] for word in ['King', 'England']]))
Но этот код приводит к следующей ошибке:
print(df[all([word in df.question for word in ['King', 'England']])])
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
File ~\anaconda3\Lib\site-packages\pandas\core\indexes\base.py:3805, in Index.get_loc(self, key)
3804 try:
-> 3805 return self._engine.get_loc(casted_key)
3806 except KeyError as err:
File index.pyx:167, in pandas._libs.index.IndexEngine.get_loc()
File index.pyx:196, in pandas._libs.index.IndexEngine.get_loc()
File pandas\\_libs\\hashtable_class_helper.pxi:7081, in pandas._libs.hashtable.PyObjectHashTable.get_item()
File pandas\\_libs\\hashtable_class_helper.pxi:7089, in pandas._libs.hashtable.PyObjectHashTable.get_item()
KeyError: False
The above exception was the direct cause of the following exception:
KeyError Traceback (most recent call last)
Cell In[9], line 2
1 print(all([word in df.question[0] for word in ['King', 'England']]))
----> 2 print(df[all([word in df.question for word in ['King', 'England']])])
File ~\anaconda3\Lib\site-packages\pandas\core\frame.py:4102, in DataFrame.__getitem__(self, key)
4100 if self.columns.nlevels > 1:
4101 return self._getitem_multilevel(key)
-> 4102 indexer = self.columns.get_loc(key)
4103 if is_integer(indexer):
4104 indexer = [indexer]
File ~\anaconda3\Lib\site-packages\pandas\core\indexes\base.py:3812, in Index.get_loc(self, key)
3807 if isinstance(casted_key, slice) or (
3808 isinstance(casted_key, abc.Iterable)
3809 and any(isinstance(x, slice) for x in casted_key)
3810 ):
3811 raise InvalidIndexError(key)
-> 3812 raise KeyError(key) from err
3813 except TypeError:
3814 # If we have a listlike key, _check_indexing_error will raise
3815 # InvalidIndexError. Otherwise we fall through and re-raise
3816 # the TypeError.
3817 self._check_indexing_error(key)
KeyError: False
Как фильтровать строки в Dataframe на основе этого условия?
Вы можете использовать .str.contains
, чтобы проверить каждое слово, а затем np.all
поверх axis=0
, чтобы объединить все логические значения для каждой строки:
import numpy as np
import pandas as pd
df = pd.DataFrame(
{
"question": [
"Who is the King of England?",
"Where is England?",
"England King",
"King",
]
}
)
df2 = df[
np.all([df['question'].str.contains(word) for word in ["King", "England"]], axis=0)
]
print(df2)
Выход:
question
0 Who is the King of England?
2 England King
возможно, df.extractall
с логическим значением может сработать.
согласно документам str.extracall
в отличие от str.extract
возвращает:
DataFrame DataFrame с одной строкой для каждого совпадения и одним столбцом для каждая группа. Его строки имеют MultiIndex с первыми уровнями, которые приходят из тематической серии. Последний уровень называется «match» и индексируется. совпадения в каждом элементе Серии. Любые имена групп захвата в для имен столбцов будет использоваться регулярное выражение pat; в противном случае будут использоваться номера групп захвата.
pat = '(' + '|'.join(['King','England']) + ')'
#'(King|England)'
out = df[df['question'].str.extractall(pat).groupby(level=0).size() > 1]
print(out)
question
0 Who is the King of England?
2 England King
дальнейшее чтение:
https://pandas.pydata.org/docs/reference/api/pandas.Series.str.extractall.html
Это будет соответствовать таким строкам, как King King
и England England
.
@Dogbert легко исправить, используя регулярное выражение или расширяя правила после str.extractall
Что вы подразумеваете под «расширением правил»?
df[(df.str.contains('England')) & (df.str.contains('King'))]