Как в pandas выбрать строки по колонке, содержащей список, заканчивающейся определённым значением?

Рейтинг: 0Ответов: 2Опубликовано: 12.04.2023

У меня есть dataframe который содержит listlike столбец.

data = {'Маршрут': ['344с', '344', '1062'],
            'Остановки': [('Ховрино', 'Совхозная'), ('Ховрино', 'Зеленая', 'Аптека', 'Левобережная', 'Совхозная'),
                          ('Ховрино', 'Рио', 'Алтуфьево')]}
df = pd.DataFrame(data, columns =['Маршрут', 'Остановки'])
df

Нужно отобрать из него строки, по последнему элементу в этой колонке. Пробую так:

df[df['Остановки'][-1] == 'Совхозная']

Выходит ошибка:

ValueError                                Traceback (most recent call last)
C:\Anaconda3\lib\site-packages\pandas\core\indexes\range.py in get_loc(self, key, method, tolerance)
    390                 try:
--> 391                     return self._range.index(new_key)
    392                 except ValueError as err:

ValueError: -1 is not in range

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_22700/3020961214.py in <cell line: 6>()
      4 df = pd.DataFrame(data, columns =['Маршрут', 'Остановки'])
      5 df
----> 6 df[df['Остановки'][-1] == 'Совхозная']

C:\Anaconda3\lib\site-packages\pandas\core\series.py in __getitem__(self, key)
    979 
    980         elif key_is_scalar:
--> 981             return self._get_value(key)
    982 
    983         if is_hashable(key):

C:\Anaconda3\lib\site-packages\pandas\core\series.py in _get_value(self, label, takeable)
   1087 
   1088         # Similar to Index.get_value, but we do not fall back to positional
-> 1089         loc = self.index.get_loc(label)
   1090         return self.index._get_values_for_loc(self, loc, label)
   1091 

C:\Anaconda3\lib\site-packages\pandas\core\indexes\range.py in get_loc(self, key, method, tolerance)
    391                     return self._range.index(new_key)
    392                 except ValueError as err:
--> 393                     raise KeyError(key) from err
    394             self._check_indexing_error(key)
    395             raise KeyError(key)

KeyError: -1

Ответы

▲ 3Принят

Можно использовать Series.str.get(), сокращенно .str[]

df = df[df['Остановки'].str[-1].eq('Совхозная')]
  Маршрут                                          Остановки
0    344с                               (Ховрино, Совхозная)
1     344  (Ховрино, Зеленая, Аптека, Левобережная, Совхо...
▲ 1

Наверняка для этого есть какая-то специальная функция, но вообще можно так, например:

df[df['Остановки'].apply(lambda x: x[-1]) == 'Совхозная']