Инвертирование логического ряда даст -1 для False и -2 для True в Панд

#python #pandas #dataframe #invert

Вопрос:

У меня есть подмножество рядов в фрейме данных Pandas, заполненных значениями bool True и False. Я пытаюсь инвертировать серию с помощью ~ .

Это исходное подмножество Серии.

 7        True
8       False
14       True
38      False
72      False
...
Name: Status, Length: 197, dtype: object
 

Теперь я использую следующий код для инвертирования значения.

 mask = ~subset_df['Status']
 

Я ожидаю, что результат будет

 7       -2
8       -1
14      -2
38      -1
72      -1
        ...

Name: Status, Length: 197, dtype: object
 

но что мне действительно нужно, так это следующий результат:

 7        False
8       True
14       False
38      True
72      True
...
Name: Status, Length: 197, dtype: object
 

Я был бы очень признателен, если бы вы дали мне знать, как инвертировать логические ряды, не преобразуя их в -1 и -2. Огромное спасибо.

Комментарии:

1. Ты пробовал mask = not subset_df['Status'] ?

2. @MarkRansom это сообщение об ошибке используется не ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Ответ №1:

По какой-то причине у вас есть серия object dtype, заполненная тем, что, вероятно, является обычным Python bool s. Применение ~ к такой серии проходит по элементам и применяет обычный ~ оператор к каждому элементу, а обычные булы Python наследуются ~ от int — они не выполняют логического отрицания для этой операции.

Вы можете сначала преобразовать свою серию в логический тип dtype, прежде чем подавать заявку ~ на получение логического отрицания:

 ~series.astype(bool)
 

В достаточно последней версии Pandas (1.0 и выше) вы можете вместо этого использовать новый логический тип dtype с astype('boolean') возможностью обнуления вместо astype(bool) .

Вы также должны выяснить, почему в вашей серии в первую очередь есть тип объекта dtype — вполне вероятно, что правильное место для решения этой проблемы находится где-то в начале вашего кода, а не здесь. Возможно, вы построили его неправильно, или вы пытались использовать NaN или None для представления отсутствующих значений.

Ответ №2:

Вы можете использовать функцию замены серии pandas в качестве:

 subset_df['Status'].replace(to_replace=[True, False], value=[False, True])
 

Это вернет другую серию с замененными значениями. Но если вы хотите изменить фактический фрейм данных, вы можете добавить параметр «inplace=True» в качестве:

 subset_df['Status'].replace(to_replace=[True, False], value=[False, True], inplace=True)
 

Комментарии:

1. Огромное спасибо!. Метод replace действительно создает противоположные значения в ряду, но могу ли я в любом случае использовать маску? Потому что мой следующий шаг-сделать incorrect= subset_df[mask][['a', 'b']].copy()

2. Спасибо! Если вам понравился мой ответ, пожалуйста, озвучьте его. И прости! Я не знаю, что такое маска у панд.

Ответ №3:

ИЗМЕНИТЬ: Если Status столбец имеет object/string тип. Здесь мы проверяем, соответствует ли Status значение True , затем мы заменяем его на False и False string на True .

 df=pd.DataFrame({
    'Status':['True', 'False', 'True', 'False', 'False']
})
df.Status = np.where(df['Status']=='True',False,True)
df
 

Выход

     Status
0   False
1   True
2   False
3   True
4   True
 

Если series boolean type да , то можно следовать приведенным ниже вариантам.

 s = pd.Series([True, False, True, False, False])
 

Два варианта

 -s
 

или

 np.invert(s)
 

Выход

 0    False
1     True
2    False
3     True
4     True
dtype: bool
 

То, что вы пробовали, работает и для df

 df=pd.DataFrame({
    'Status':[True, False, True, False, False]
})
df['Status'] = ~df['Status']
df
 

Выход

     Status
0   False
1   True
2   False
3   True
4   True
 

Комментарии:

1. большое вам спасибо за предложение. Не знаю почему , но при использовании -s или np.invert(s) вывод все равно будет dtype = object вместо bool. И затем, если я применяю следующую функциональную incorrect= subset_df[mask][['a', 'b']].copy() ошибку: «Ни один из [Int64Index([-1, 0, -1, 0, 0, 0, 0, 0, 0, 0,н … n 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],n dtype=’int64′, длина=197)] находятся в [столбцах]»

2. хорошо, похоже Status , что столбец-это object тип, а не логический тип. Обновил ответ, чтобы поддержать это.

3. это имеет смысл, просто интересно, почему мы пишем такую логику np.where(df['Status']=='True',False,True)

4. Также я думаю df.Status = np.where(df['Status']=='True',False,True) , что будет работать только в том случае, если тип является строковым, но не объектным. Потому что, когда тип является объектом, и сравнение с «Истинным» всегда будет ложным.

5. Обновлено объяснение np.where в решении. Это решение будет работать с обоими string and object типами. Я позволю вам изучить сходства между string and object пандами.