#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
пандами.