Фрейм данных Pandas, если условие использует isin в строке

#pandas #dataframe

Вопрос:

Вот примерный набор данных.

 test=pd.DataFrame({'class': ['A', 'B', 'C', 'A'],
                   'Value': [2, 1, 5, 4]
                   })
 

Я хотел бы изменить столбец «Значение» на основе приведенного ниже условия
«Если класс находится в» A » или » B «и значение>=4, измените значение на «0», в противном случае оставьте прежним»
Вот встроенная функция

 def test_class(c):
    if c[(c['class'].isin(['A','B'])) amp; (c['Value']>=4)]:
        return 0
    else:
        return  c["Value"]
 

Применение к фрейму данных

 test['Value'] = test.apply(test_class, axis=1)
 

Выбрасывание ниже ошибки

введите описание изображения здесь

Ожидаемый результат, и ниже должно быть выделено изменение стоимости

введите описание изображения здесь

Ответ №1:

Необходимо ли в вашем случае использовать функцию «test_class» с циклом? Если нет, вы могли бы сделать:

 test.loc[(test['class'].isin(['A','B'])) amp; (test['Value']>=4), 'Value'] = 0
 

Выход:

     class   Value
0       A       2
1       B       1
2       C       5
3       A       0
 

Ответ №2:

Внутри вашей функции c['class'] находится простая строка, поэтому вы можете сделать:

 def test_class(c):
    if (c['class'] in ['A','B']) amp; (c['Value']>=4):
        return 0
    else:
        return  c["Value"]

test['Value'] = test.apply(test_class, axis=1)
 

Однако лучше векторизовать функцию следующим образом:

 def test_class(c):

    return np.where((c['class'].isin(['A','B'])) amp; (c['Value']>=4), 0,
                    c['Value'])
 

Тогда вы можете позвонить:

 test['Value'] = test_class(test)
 

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

1. Спасибо, но я вижу это «Ошибка значения: операнды не могут передаваться вместе с фигурами (1,2) () (4,)»

2. @HKE Я был слишком быстр, тебе нужно убрать выдру c[...] . См. Обновленный ответ

Ответ №3:

Попробуйте это:

 np.where((test['class'].isin(['A', 'B']))amp;(test.Value.ge(4)), 0, test['Value'])
 

Вы также можете использовать mask метод:

 test.Value.mask((test['class'].isin(['A', 'B']))amp;(test.Value.ge(4)), other=0)
 

Выход:

     class   Value   new_value
0     A       2         2
1     B       1         1
2     C       5         5
3     A       4         0