Есть ли способ использовать (если число в диапазоне) при использовании .apply в python?

#python #dataframe #range

Вопрос:

У меня есть фрейм данных, который выглядит примерно так

Разница Минута Макс
2.5 -5 5
7.3 -3 3
0.1 -0.1 0.1

Числа в столбцах «Min» и «Max» отличаются от строки к строке, но всегда принимают значение Min = -Max. То, что я хочу создать, — это последний столбец, который сообщает мне, соответствует ли значение в столбце «Разница» значениям в столбце «Минимум» и «Максимум». Что-то вроде этого:

Разница Минута Макс Сигнал
2.5 -5 5 Сигнал
7.3 -3 3 Нет Сигнала
0.1 -0.1 0.1 Сигнал

«Сигнал» и «Нет сигнала» также можно было бы заменить на «Истина» или «Ложь», если бы был способ использовать булевы операторы.

Код, который я сейчас использую, выглядит следующим образом.

 df['Signal'] = df['Difference'].apply(lambda x: 'Signal' if x in range((df['Min']), (df['Max'])) else 'No Signal')
 

Это дает мне код ошибки

   File "<ipython-input-52-13b6ff6e946a>", line 5
df['Signal'] = df['Difference'].apply(lambda x: 'Signal' if x in range((df['Min']), (df['Max'])) else 'No Signal')
 ^
SyntaxError: invalid syntax
 

Я также попробовал другой подход со следующим кодом

 df['Signal'] = df['Difference'].apply(lambda x: 'Signal' if df['Min'] <= x <= df['Max'] else 'No Signal')
 

Это затем дало мне сообщение об ошибке

 ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
 

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

Любая помощь будет очень признательна.

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

1. вы можете попробовать df['difference'].le(df['max']) amp; df['difference'].ge(df['min'])

2. @Epsi95 Большое вам спасибо. Это все исправило! Я добавлю это в свой список для дальнейшего использования.

3. Вы можете использовать apply для полной строки фрейма данных: df['Signal'] = df.apply(lambda row: 'Signal' if row['Min'] <= row['Difference'] <= row['Max'] else 'No Signal', axis = 1) (исправление вашего опубликованного решения).

4. @codingnewbie проверьте ответ

Ответ №1:

Простое исправление вашего опубликованного решения с помощью apply:

 df['Signal'] = df.apply(lambda row: 'Signal' if row['Min'] <= row['Difference'] <= row['Max'] else 'No Signal', axis = 1)
 
  • В приведенном выше примере строка-это целая строка фрейма данных, позволяющая использовать строку[‘Min’] и т. Д. для доступа к нужным элементам столбца.
  • ось = 1 означает, что мы используем применить к строкам.

Ответ №2:

Вот простое решение, использующее тот факт, что Min значение всегда - Max :

 df['Signal'] = df.Difference.abs() <= df.Min.abs()
 

Это создает логический столбец, содержащий True для тех строк, в которых выполняется условие.

Ответ №3:

Вы можете использовать этот pd.Series.between метод для этого:

 import pandas as pd

df = pd.DataFrame({
    'Difference': [2.5, 7.3, 0.1],
    'Min': [-5, -3, -0.1],
    'Max': [5, 3, 0.1],
    })

print(df['Difference'].between(df['Min'], df['Max']))
 

Вывод представляет собой логический ряд:

 0     True
1    False
2     True
dtype: bool
 

Тогда нам просто нужно map эти значения, чтобы получить нужный 'Signal' вам столбец:

 df['Signal'] = df['Difference'].between(df['Min'], df['Max']).map({True: 'Signal', False: 'No Signal'})

print(df)
 

выход:

    Difference  Min  Max     Signal
0         2.5 -5.0  5.0     Signal
1         7.3 -3.0  3.0  No Signal
2         0.1 -0.1  0.1     Signal
 

Ответ №4:

Вот решение, которое вы можете попробовать, используя between np.where

 df['Signal'] = (
    np.where(df['Difference'].between(df['Min'], df['Max']), 'Signal', 'No Signal')
)
 

    Difference  Min  Max     Signal
0         2.5 -5.0  5.0     Signal
1         7.3 -3.0  3.0  No Signal
2         0.1 -0.1  0.1     Signal
 

Ответ №5:

Вам необходимо применить функцию к фрейму данных, если вы хотите получить доступ к нескольким значениям col/строк (убедитесь, что вы указали правильную ось).:

 df['Signal'] = df.apply(lambda x: 'Signal' if x['Min'] <= x['Difference'] <= x['Max'] else 'No Signal', axis=1)
 

Ошибка относится к тому факту, что вы сравниваете одно значение с рядом (многими значениями). Панды не знают, с каким значением в серии вы хотите сравнить x .

В качестве альтернативы вы можете использовать numpy’s where и pandas’ between :

 df['Signal'] = np.where(df['Difference'].between(df['Min'], df['Max']), 'Signal', 'No Signal')
 

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

1. Спасибо. Я уже пробовал функцию .between раньше, но не мог точно понять, как ее использовать. Это действительно полезно.

Ответ №6:

Нет необходимости использовать apply по строкам, что может быть очень медленным и не предпочтительным способом, используйте векторизованный подход.

 df['Signal'] = (df['Difference'].le(df['Max']) amp; df['Difference'].ge(df['Min'])).map({
    True: 'Signal',
    False: 'No Signal'
})

print(df)

#    Difference  Min  Max     Signal
# 0         2.5 -5.0  5.0     Signal
# 1         7.3 -3.0  3.0  No Signal
# 2         0.1 -0.1  0.1     Signal