Панды: замена логическими значениями дает противоречивые результаты - PullRequest
0 голосов
/ 11 июня 2018

У меня есть фрейм данных, который состоит из галочек типа x и v, которые я заменяю логическими значениями со следующей строкой:

df.replace({'v': True, 'x': False}, inplace=True)

Перед запуском df.replace() тип всех столбцов в соответствии сdf.dtypes равно object.После replace() все остальные столбцы по-прежнему object, за исключением одного столбца, который имеет тип bool, а значения в нем имеют тип numpy.bool_.Pycharm показывает этот конкретный столбец с красным фоном для значений True, как показано ниже.

pandas boolean dataframe

Почему это может происходить?object не подходит для хранения логических значений?И почему pandas меняет dtype с object на bool для этого отдельного столбца?Что именно контролирует это и как я могу принудительно установить dtype на object?

Будет ли причина иметь все столбцы вместо pandas.np.bool, например, из соображений производительности?

1 Ответ

0 голосов
/ 11 июня 2018

Pandas хранит серию изнутри как массивы NumPy.Когда серия имеет смешанные типы, Pandas / NumPy должна принять решение: она выбирает тип, который охватывает все типы в этой серии.В качестве тривиального примера, если у вас есть серия целых чисел с типом int и вы измените одно значение на float, ваша серия станет типа float.

В этом примере ваши 0-й и 2-йсерия имеет NaN значений.Теперь NaN или np.nan считается float (попробуйте type(np.nan), это вернет float), а True / False считается логическим.Единственный способ, которым NumPy может хранить эти значения, - это использовать dtype object, который является просто набором указателей (очень похоже на список).

Ваш 1-й столбец, с другой стороны, имеет только логические значения и можетхраниться с типом bool.Преимущество здесь в том, что вы не используете коллекцию указателей. NumPy может выделить непрерывный блок памяти для этого массива.Это даст преимущества в производительности по сравнению с серией object или list.

. Вы можете проверить все вышеперечисленное самостоятельно.Вот несколько примеров:

s1 = pd.Series([True, False])
print(s1.dtype)  # bool

s2 = pd.Series([True, False, np.nan])
print(s2.dtype)  # object

s3 = pd.Series([True, False, 0, 1])
print(s3.dtype)  # object

Последний пример интересен тем, что в Python True == 1 и False == 0 оба возвращают True, поскольку bool можно считать подклассом int.Поэтому внутренне Pandas / NumPy приняла решение не применять это равенство и выбирать один или другой.Следствием этого является то, что вам рекомендуется проверять тип вашей серии при работе со смешанными типами.

Обратите также внимание, что Pandas выполняет проверки dtypes при обновлении значений:

s1 = pd.Series([True, 5.4])
print(s1.dtype)  # object

s1.iloc[-1] = False
print(s1.dtype)  # bool
...