ValueError: (‘Истинное значение серии не однозначно после применения условия if/else в датафреймах Pandas

Вопрос или проблема

Я хочу создать новую переменную для датафрейма details, названную lower, после итерации по нескольким data frames.

  • list1 – это список строковых значений столбца с именем variable_name в details.
  • vars_df – это еще один датафрейм с 2 столбцами, а именно variable_name и direction. Оба столбца содержат строковые значения. vars_df.shape = (19,2). Некоторые значения variable_name в vars_df присутствуют в list1, а также в data_set. data_set.shape = (32,107). df.shape = (96,1).

Следующий код, который нацелен на выполнение вышеуказанного:

    def get_value(df,list1):
        if ((vars_df['variable_name']) in list1) & (vars_df['direction'] =='up'):
            data = data_set[df['variable_name']]
        else:
            data = data_set[df['variable_name']]-20
            if data < 0:
               data = 0
            else:
               data = data
       return data    

details['lower'] = details.apply(get_value,list1=li,result_type="expand",axis=1) 

выдает эту ошибку:

ValueError: ('Истинное значение серии неоднозначно. Используйте a.empty, a.bool(), a.item(), a.any() или a.all().', 'произошло по индексу 0')

Я обратился к вопросу.Истинное значение серии неоднозначно, но я все еще не могу исправить ошибку

(Предполагая, что ошибка возникает во 2-й строке)

Этот вопрос на StackOverflow имеет отличный ответ на вашу проблему

В основном, измените

 if ((vars_df['variable_name']) in list1) & (vars_df['direction'] =='up'):

на это

if (((vars_df['variable_name']) in list1) & (vars_df['direction'] =='up')).any():

или на это, если все значения должны быть истинными

if (((vars_df['variable_name']) in list1) & (vars_df['direction'] =='up')).all():

Надеюсь, это поможет 🙂

Ответ или решение

Ошибка ValueError: ('The truth value of a Series is ambiguous' ...), возникающая при выполнении вашего кода в Pandas, указывает на то, что в вашем условии if вы пытаетесь использовать булевую серию без явного указания, как обрабатывать многозначные результаты. Давайте рассмотрим вашу проблему более подробно и предложим решение.

Проблема

Ваш код пытается проверить несколько условий в if:

if ((vars_df['variable_name']) in list1) & (vars_df['direction'] =='up'):

При использовании такого синтаксиса проверка (vars_df['variable_name']) in list1 возвращает серию, а не одно булево значение. Это создаёт неоднозначность, когда интерпретируется результат при выполнении условия if, так как Pandas не может определить, какое значение (истина или ложь) нужно использовать.

Решение

Для решения этой проблемы можно изменить ваш код, используя метод .any() или .all(), чтобы явно указать, как обрабатывать результат проверки. Это позволит избежать неоднозначности.

Изменённый Код

Ниже приведен исправленный вариант вашей функции get_value:

def get_value(df, list1):
    # Проверяем, если хотя бы одно значение в vars_df['variable_name'] находится в list1
    # и соответствует условию, что vars_df['direction'] равен 'up'
    condition = (vars_df['variable_name'].isin(list1)) & (vars_df['direction'] == 'up')
    if condition.any():  # Если хотя бы одно значение истинно
        data = data_set[df['variable_name']]
    else:
        data = data_set[df['variable_name']] - 20
        data = data.clip(lower=0)  # Обрезаем значения, чтобы они не были меньше 0
    return data    

# Применяем функцию к DataFrame details
details['lower'] = details.apply(get_value, list1=list1, axis=1)

Объяснение изменений

  1. isin(): Вместо оператора in используется метод .isin(), который возвращает серию булевых значений, указывающих, находятся ли значения в списке list1. Это устраняет неоднозначность с проверкой как всей серии.

  2. condition.any(): Метод .any() проверяет, содержит ли хотя бы одно из значений True. Если нужно проверять все значения, тогда используйте .all().

  3. clip(lower=0): Вместо конструкции if ... < 0, которая требует дополнительного условного оператора, можно использовать метод clip, который эффективно указывает нижнюю границу значений.

Заключение

Используя ясные методы, такие как .isin() и .any(), а также функции для обработки значений, такие как clip, вы можете избежать проблем с неоднозначностью и сделать код более читаемым и эффективным. Если у вас возникнут дополнительные вопросы или потребуются уточнения, не стесняйтесь обращаться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...