Вопрос или проблема
Я хочу создать новую переменную для датафрейма 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)
Объяснение изменений
-
isin()
: Вместо оператораin
используется метод.isin()
, который возвращает серию булевых значений, указывающих, находятся ли значения в спискеlist1
. Это устраняет неоднозначность с проверкой как всей серии. -
condition.any()
: Метод.any()
проверяет, содержит ли хотя бы одно из значенийTrue
. Если нужно проверять все значения, тогда используйте.all()
. -
clip(lower=0)
: Вместо конструкцииif ... < 0
, которая требует дополнительного условного оператора, можно использовать методclip
, который эффективно указывает нижнюю границу значений.
Заключение
Используя ясные методы, такие как .isin()
и .any()
, а также функции для обработки значений, такие как clip
, вы можете избежать проблем с неоднозначностью и сделать код более читаемым и эффективным. Если у вас возникнут дополнительные вопросы или потребуются уточнения, не стесняйтесь обращаться за помощью.