Посмотрите пример в здесь , у Стивена есть ясный ответ для вас:
Так вот что происходит, начиная с метода верхнего уровня (Button1_Click for UI / MyController.Get для ASP.NET):
- Метод верхнего уровня вызывает GetJsonAsync (в контексте UI / ASP.NET).
- GetJsonAsync запускает REST запрос, вызвав HttpClient.GetStringAsync (все еще в контексте).
- GetStringAsync возвращает незавершенную задачу, указывая, что запрос REST не завершен.
- GetJsonAsync ожидает задачу, возвращенную GetStringAsync. Контекст захвачен и будет использоваться для продолжения использования метода GetJsonAsync позже. GetJsonAsync возвращает незавершенную задачу, указывая, что метод GetJsonAsync не завершен.
- Метод верхнего уровня синхронно блокирует задачу, возвращенную GetJsonAsync. Это блокирует контекстный поток.
- ... В конце концов, запрос REST завершится. Это завершает задачу, которая была возвращена GetStringAsync.
- Продолжение для GetJsonAsync теперь готово к запуску и ожидает, что контекст будет доступен, чтобы он мог выполняться в контексте.
- Тупик. Метод верхнего уровня блокирует поток контекста, ожидая завершения GetJsonAsync, и GetJsonAsync ожидает, что контекст будет бесплатным, чтобы он мог завершить. Для примера пользовательского интерфейса «контекст» представляет собой контекст пользовательского интерфейса; для примера ASP.NET «контекст» представляет собой контекст запроса ASP.NET.
Еще одна ссылка, которую вы должны прочитать:
Операторы python or
и and
требуют truth
-значений. Для pandas
они считаются двусмысленными, поэтому вы должны использовать «побитовые» операции |
(или) или &
(и):
result = result[(result['var']>0.25) | (result['var']<-0.25)]
Они перегружены для данных типов данных, чтобы получить element-wise or
(или and
).
Просто добавим еще одно объяснение этому утверждению:
Исключение выбрано, когда вы хотите получить bool
в pandas.Series
:
>>> import pandas as pd
>>> x = pd.Series([1])
>>> bool(x)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
То, что вы нажали, было местом, где оператор неявно преобразовал операнды в bool
(вы использовали or
, но это также происходит для and
, if
и while
):
>>> x or x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> x and x
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> if x:
... print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> while x:
... print('fun')
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Помимо этих 4-х инструкций существует несколько функций-питонов, которые скрывают некоторые вызовы bool
(например, any
, all
, filter
, ...) они обычно не проблематичны с pandas.Series
, но для полноты я хотел упомянуть их.
В вашем случае исключение не очень полезно, потому что оно не упоминает правильные альтернативы. Для and
и or
вы можете использовать (если вы хотите сравнить по элементам):
numpy.logical_or
: >>> import numpy as np
>>> np.logical_or(x, y)
или просто |
: >>> x | y
numpy.logical_and
: >>> np.logical_and(x, y)
или просто оператор &
: >>> x & y
Если вы используете операторы, затем убедитесь, что вы правильно установили свою скобку из-за приоритета оператора .
Есть несколько логических функций numpy , которые должен работать pandas.Series
.
Альтернативы, упомянутые в Исключении, более подходят, если вы столкнулись с этим при выполнении if
или while
. Вкратце объясню каждый из них:
>>> x = pd.Series([])
>>> x.empty
True
>>> x = pd.Series([1])
>>> x.empty
False
Python обычно интерпретирует контейнеры len
gth (например, list
, tuple
, ...) как значение истины, если оно не имеет явной булевой интерпретации. Поэтому, если вы хотите выполнить проверку типа python, вы можете сделать: if x.size
или if not x.empty
вместо if x
. Series
содержит одно и только одно логическое значение: >>> x = pd.Series([100])
>>> (x > 50).bool()
True
>>> (x < 50).bool()
False
.bool()
, но работает даже для не логического содержимого): >>> x = pd.Series([100])
>>> x.item()
100
>>> x = pd.Series([0, 1, 2])
>>> x.all() # because one element is zero
False
>>> x.any() # because one (or more) elements are non-zero
True
Для логической логики используйте &
и |
.
np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
>>> df
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
2 0.950088 -0.151357 -0.103219
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
>>> df.loc[(df.C > 0.25) | (df.C < -0.25)]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
Чтобы узнать, что происходит, вы получаете столбец логических значений для каждого сравнения, например
df.C > 0.25
0 True
1 False
2 False
3 True
4 True
Name: C, dtype: bool
Когда у вас есть несколько критериев, вы получите несколько возвращенных столбцов. Вот почему логика объединения неоднозначна. Использование and
или or
обрабатывает каждый столбец отдельно, поэтому вам сначала нужно свести этот столбец к одному логическому значению. Например, чтобы увидеть, истинно ли любое значение или все значения в каждом столбце.
# Any value in either column is True?
(df.C > 0.25).any() or (df.C < -0.25).any()
True
# All values in either column is True?
(df.C > 0.25).all() or (df.C < -0.25).all()
False
Один из пронумерованных способов добиться того же самого - это объединить все эти столбцы вместе и выполнить соответствующие логика.
>>> df[[any([a, b]) for a, b in zip(df.C > 0.25, df.C < -0.25)]]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
Для получения дополнительной информации см. Boolean Indexing в документах.
Этот отличный ответ очень хорошо объясняет, что происходит, и дает решение. Я хотел бы добавить другое решение, которое может быть подходящим в подобных случаях: с помощью метода query
:
result = result.query("(var > 0.25) or (var < -0.25)")
См. Также http: // pandas. pydata.org/pandas-docs/stable/indexing.html#indexing-query.
(Некоторые тесты с фреймворком данных, с которыми я сейчас работаю, показывают, что этот метод немного медленнее, чем используя побитовые операторы в рядах булевых: 2 мс против 870 мкс)
Предупреждение: по крайней мере, одна ситуация, когда это не просто, когда имена столбцов являются выражениями python. Я имел столбцы с именами WT_38hph_IP_2
, WT_38hph_input_2
и log2(WT_38hph_IP_2/WT_38hph_input_2)
и хотел выполнить следующий запрос: "(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
Я получил следующее исключение:
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
Я предполагаю, что это произошло потому, что анализатор запросов пытался что-то сделать с первого два столбца вместо того, чтобы идентифицировать выражение с именем третьего столбца.
Предлагается возможное обходное решение здесь .
Или, альтернативно, вы можете использовать модуль Operator. Более подробная информация здесь Документы Python
import operator
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
df.loc[operator.or_(df.C > 0.25, df.C < -0.25)]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.4438