Pandas: ошибка при проверке шаблона двоичного флага

У меня есть кадр данных, в котором один из столбцов типа int хранит шаблон двоичного флага:

import pandas as pd

df = pd.DataFrame({'flag': [1, 2, 4, 5, 7, 3, 9, 11]})

Я попытался выбрать строки со значением, соответствующим 4, как это обычно делается (с двоичным кодом и оператором):

df[df['flag'] & 4]

Но это не удалось с:

KeyError: ни один из [Int64Index([0, 0, 4, 4, 4, 0, 0, 0], dtype='int64')] не находится в [столбцах]

Как на самом деле выбрать строки, соответствующие двоичному шаблону?


person sophros    schedule 19.06.2021    source источник


Ответы (2)


Выбор побитового флага работает так, как вы ожидаете:

>>> df['flag'] & 4
0    0
1    0
2    4
3    4
4    4
5    0
6    0
7    0
Name: flag, dtype: int64

Однако, если вы передадите это df.loc[], вы запросите многократное получение индексов 0 и 4, или, если вы используете df[] напрямую, вы запросите столбец, у которого Int64Index[...] в качестве заголовка столбца.

Вместо этого вы должны принудительно преобразовать в логический индексатор:

>>> (df['flag'] & 4) != 0
0    False
1    False
2     True
3     True
4     True
5    False
6    False
7    False
Name: flag, dtype: bool
>>> df[(df['flag'] & 4) != 0]
   flag
2     4
3     5
4     7
person Cimbali    schedule 19.06.2021

Несмотря на то, что в Pandas & или | используется как логический оператор для указания условий но в то же время используя Series в качестве аргумента для якобы логического оператора приводит не к серии логических значений, а к числам.

Зная, что вы можете использовать любой из следующих подходов для выбора строк на основе двоичного шаблона:

  • Поскольку результатом <int> & <FLAG> всегда является <FLAG>, вы можете использовать:

    df[df['flag'] & 4 == 4]
    

который (из-за приоритета операторов) оценивается как:

  df[(df['flag'] & 4) == 4]
  • в качестве альтернативы вы можете использовать apply и сопоставить результат непосредственно с bool:

    df[df['flag'].apply(lambda v: bool(v & FLAG))]
    

Но это выглядит очень громоздко и, вероятно, будет намного медленнее.

В любом случае результат будет ожидаемым:

    flag
2   4
3   5
4   7
person sophros    schedule 19.06.2021