Сообщить об ошибке.

Метод .isin() объектов DataFrame/Series в pandas

Проверка наличия элементов DataFrame в списке значений

Содержание:


Обзор применения метода .isin() объектов DataFrame/Series

Рассмотрим метод Series.isin(), который возвращает логический вектор, истинный везде, где элементы Series существуют в переданном списке. Такое поведение позволяет выбрать строки, в которых один или несколько столбцов имеют нужные значения:

>>> import pandas as pd
>>> import numpy as np
>>> s = pd.Series(np.arange(5), index=np.arange(5)[::-1], dtype='int64')
>>> s
# 4    0
# 3    1
# 2    2
# 1    3
# 0    4
# dtype: int64

>>> s.isin([2, 4, 6])
# 4    False
# 3    False
# 2     True
# 1    False
# 0     True
# dtype: bool

>>> s[s.isin([2, 4, 6])]
# 2    2
# 0    4
# dtype: int64

Этот же метод доступен для объектов Index и полезен в тех случаях, когда неизвестно, какая из искомых меток на самом деле присутствует:

>>> s[s.index.isin([2, 4, 6])]
# 4    0
# 2    2
# dtype: int64

>>> s.reindex([2, 4, 6])
# 2    2.0
# 4    0.0
# 6    NaN
# dtype: float64

В дополнение к сказанному, MultiIndex позволяет выбрать отдельный уровень для использования при проверке членства:

>>> s_mi = pd.Series(np.arange(6), index=pd.MultiIndex.from_product([[0, 1], ['a', 'b', 'c']]))
>>> s_mi
# 0  a    0
#    b    1
#    c    2
# 1  a    3
#    b    4
#    c    5
# dtype: int64

>>> s_mi.iloc[s_mi.index.isin([(1, 'a'), (2, 'b'), (0, 'c')])]
# 0  c    2
# 1  a    3
# dtype: int64

>>> s_mi.iloc[s_mi.index.isin(['a', 'c', 'e'], level=1)]
# 0  a    0
#    c    2
# 1  a    3
#    c    5
# dtype: int64

В DataFrame также есть метод .isin(). При вызове DataFrame.isin() необходимо передать множество значений в виде списка или словаря. Если values является списком, то DataFrame.isin() возвращает DataFrame логических значений, который имеет ту же форму, что и исходный DataFrame(везде с True, где значение элемента DataFrame имеется в переданной последовательности).

>>> df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': ['a', 'b', 'f', 'n'],
...                    'ids2': ['a', 'n', 'c', 'n']})

>>> values = ['a', 'b', 1, 3]
>>> df.isin(values)
#     vals    ids   ids2
# 0   True   True   True
# 1  False   True  False
# 2   True  False  False
# 3  False  False  False

Часто требуется сопоставить определенные значения с определенными столбцами. Для решения такой задачи необходимо создать словарь dict, где ключ - это название метки столбца, а значение - список элементов, которые необходимо проверить.

>>> values = {'ids': ['a', 'b'], 'vals': [1, 3]}
>>> df.isin(values)
#     vals    ids   ids2
# 0   True   True  False
# 1  False   True  False
# 2   True  False  False
# 3  False  False  False

Чтобы вернуть DataFrame логических значений, значения которых отсутствуют в исходном DataFrame, необходимо использовать оператор ~:

>>> values = {'ids': ['a', 'b'], 'vals': [1, 3]}
>>> ~df.isin(values)
#     vals    ids  ids2
# 0  False  False  True
# 1   True  False  True
# 2  False   True  True
# 3   True   True  True

Чтобы быстро выбрать подмножество данных, которые соответствуют заданным критериям, можно объединить DataFrame.isin() с методами DataFrame.any() и DataFrame.all():

>>> values = {'ids': ['a', 'b'], 'ids2': ['a', 'c'], 'vals': [1, 3]}
>>> row_mask = df.isin(values).all(1)
>>> df[row_mask]
#    vals ids ids2
# 0     1   a    a

DataFrame.isin(values):

Метод DataFrame.isin() библиотеки pandas проверяет наличие каждого элемента DataFrame в значениях, передаваемых в values.

Аргумент values может принимать итерируемый объект (например список list), Series, DataFrame или словарь dict.

Результат будет истинным только в том случае, если все индексные метки совпадают.

  • Если values является Series, то для получения True должны совпасть еще индексные метки.
  • Если values является dict, то ключи должны быть именами столбцов, которые должны совпадать.
  • Если values является DataFrame, то индексные метки DataFrame.Index и DataFrame.columns должны совпадать.

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

Метод возвращает DataFrame логических значений, показывающих, содержится ли каждый элемент DataFrame в values.

Примеры использования DataFrame.isin():

>>> import pandas as pd
df = pd.DataFrame({'num_legs': [2, 4], 'num_wings': [2, 0]},
                  index=['falcon', 'dog'])
>>> df
#         num_legs  num_wings
# falcon         2          2
# dog            4          0

Если аргумент values является списком, то идет простая проверка, все ли значения в DataFrame присутствуют в списке

>>> df.isin([0, 2])
#         num_legs  num_wings
# falcon      True       True
# dog        False       True

И так, получены значения bool для каждого элемента DataFrame. И что теперь с этим делать? Для получения требуемых результатов необходимо использовать "логическую индексацию":

Для просмотра всех совпавших элементов DataFrame (НЕ совпавшие значения будут заменены на NaN):

>>> df[df.isin([0, 2])]
#         num_legs  num_wings
# falcon       2.0          2
# dog          NaN          0

Для просмотра столбцов, в которых значения присутствуют во всеx строках, дополнительно можно использовать метод DataFrame.all():

>>> df.loc[:, df.isin([0, 2]).all()]
#         num_wings
# falcon          2
# dog             0

Для просмотра строк, в которых значения присутствуют во всех столбцах, дополнительно можно использовать метод DataFrame.all(axis=1):

>>> df.loc[df.isin([0, 2]).all(axis=1)]
#         num_legs  num_wings
# falcon         2          2

Чтобы проверить значений DataFrame на ОТСУТСТВИЕ в списке, то необходимо использовать оператор отрицания ~:

>>> ~df.isin([0, 2])
#         num_legs  num_wings
# falcon     False      False
# dog         True      False

# используем логическую индексацию
# строки, где есть НЕ совпавшие значения
>>> df.loc[~df.isin([0, 2]).all(axis=1)]
#      num_legs  num_wings
# dog         4          0

# столбцы, где есть НЕ совпавшие значения
>>> df.loc[:, ~df.isin([0, 2]).all()]
#         num_legs
# falcon         2
# dog            4

Когда аргумент values является словарем, то можно передавать значения для проверки для каждого столбца отдельно:

>>> df.isin({'num_wings': [0, 3]})
#         num_legs  num_wings
# falcon     False      False
# dog        False       True

Если аргумент values является Series или DataFrame, то индекс и столбец должны совпадать. Обратите внимание, что 'falcon' не совпадает с num_legs.

other = pd.DataFrame({'num_legs': [8, 3], 'num_wings': [0, 2]},
                     index=['spider', 'falcon'])
>>> df.isin(other)
#         num_legs  num_wings
# falcon     False       True
# dog        False      False

# используем логическую индексацию
>>> df[df.isin(other)]
#         num_legs  num_wings
# falcon       NaN        2.0
# dog          NaN        NaN

# смотрим на оба `DataFrame` для проверки
>>> df
#         num_legs  num_wings
# falcon         2          2
# dog            4          0
>>> other
#         num_legs  num_wings
# spider         8          0
# falcon         3          2 (есть совпадение )

Series.isin(values):

Метод Series.isin() библиотеки pandas проверяет содержатся ли элементы Series в последовательности values.

Возвращает логическое значение Series - маску логических значений Series, которая показывает, находится ли каждый элемент Series в последовательности values.

Аргумент values представляет собой последовательность проверяемых значений. Передача одной строки вызовет ошибку TypeError. Вместо этого превратите строку в список из одного элемента. Может принимать множество или список.

Примеры использования Series.isin():

s = pd.Series(['llama', 'cow', 'llama', 'beetle', 'llama',
               'hippo'], name='animal')

>>> s.isin(['cow', 'llama'])
# 0     True
# 1     True
# 2     True
# 3    False
# 4     True
# 5    False
# Name: animal, dtype: bool

И так, получены значения bool для Series. И что теперь с этим делать? Для получения результатов необходимо использовать "логическую индексацию":

>>> s.loc[s.isin(['cow', 'llama'])]
# 0    llama
# 1      cow
# 2    llama
# 4    llama
# Name: animal, dtype: object

Чтобы инвертировать логические значения, используем оператор ~:

>>> ~s.isin(['cow', 'llama'])
# 0    False
# 1    False
# 2    False
# 3     True
# 4    False
# 5     True
# Name: animal, dtype: bool

# для просмотра значений `Series`
# используем логическую индексацию
>>> s.loc[~s.isin(['cow', 'llama'])]
# 3    beetle
# 5     hippo
# Name: animal, dtype: object

Передача одной строки как s.isin('llama') вызовет ошибку. Чтобы избежать такого поведения используем список из одного элемента:

>>> s.isin(['llama'])
# 0     True
# 1    False
# 2     True
# 3    False
# 4     True
# 5    False
# Name: animal, dtype: bool

Строки и целые числа различны и поэтому не могут быть сопоставимы:

>>> pd.Series([1]).isin(['1'])
# 0    False
# dtype: bool

>>> pd.Series([1.1]).isin(['1.1'])
# 0    False
# dtype: bool