시리즈의 진실 가치는 모호합니다. a.empty, a.bool (), a.item (), a.any () 또는 a.all ()을 사용하십시오.


366

or조건으로 결과 데이터 프레임을 필터링하는 데 문제가 있습니다. 결과 dfvar0.25보다 크고 -0.25보다 작은 모든 열 값 을 추출하기를 원합니다 .

아래의 논리는 모호한 진실 값을 제공하지만이 필터링을 두 개의 별도 작업으로 분리하면 작동합니다. 여기서 무슨 일이 일어나고 있습니까? 제안 된 위치를 잘 모르겠습니다 a.empty(), a.bool(), a.item(),a.any() or a.all().

 result = result[(result['var']>0.25) or (result['var']<-0.25)]

46
|대신 사용or
MaxU

1
해결 방법은 다음과 같습니다.abs(result['var'])>0.25
ColinMac

답변:


566

orand파이썬 문은 필요 truth-values합니다. 들어 pandas사용 "비트 단위"해야하므로 이러한 모호함으로 간주된다 |(또는) 또는 &작업 (과) :

result = result[(result['var']>0.25) | (result['var']<-0.25)]

이들은 이러한 종류의 데이터 구조에 대해 과부하되어 요소 단위 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, ifwhile).

>>> 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하지만 완전성을 위해 내가이 언급하고 싶었다는.


귀하의 경우 예외는 올바른 대안을 언급하지 않기 때문에 실제로 도움이되지 않습니다 . for andor당신은 사용할 수 있습니다 (요소 별 비교를 원한다면) :

  • 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.


당신이 일을 할 때 발생하는 경우 예외에 언급 된 대안이 더 적합하다 ifwhile. 나는 이들 각각을 간단히 설명 할 것이다 :

  • 시리즈가 비어 있는지 확인하려면 :

    >>> x = pd.Series([])
    >>> x.empty
    True
    >>> x = pd.Series([1])
    >>> x.empty
    False

    파이썬은 일반적으로 해석 len(같은 용기의 GTH을 list, tuple그것을 명시 적 부울 해석이없는 경우, ...) 진리 값으로. 당신이 원한다면 그래서 파이썬처럼 체크, 당신은 할 수 : if x.sizeif 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
  • 당신이 있는지 확인하려면 모든 또는 어떤 항목이 비어 있지 않거나 거짓되지 아니 0이 :

    >>> 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

왜이 파이썬 연산자가 팬더 시리즈를 처리하기 위해 오버로드되지 않습니까?
Mudit Jain

@MuditJain 직접 오버로드 할 수있는 방법이 없습니다 and, or그리고 not파이썬은. 이 연산자 bool는 피연산자 리턴에서 직접 사용 합니다. 그리고 Pandas / NumPy가 오버로드 된 방식 ValueError으로 이러한 데이터 구조의 진실 가치를 모호하기 때문에 이미 제기했습니다 .
MSeifert

해결책은 괜찮지 만 설명은 그리 멀다
blacksheep

2
@blacksheep 내가 더 잘 설명 할 수있는 제안이 있습니까?
MSeifert

좋은 설명입니다. 실제로 더 추상적 인 예제가 실패한 방식으로 비트 대 논리를 이해하는 데 도움이되었습니다.
rocksNwaves

41

부울 논리의 경우 &및을 사용하십시오 |.

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취급하므로 먼저 해당 열을 단일 부울 값으로 줄여야합니다. 예를 들어, 각 열의 값 또는 모든 값이 True인지 확인하십시오.

# 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

자세한 내용 은 문서의 부울 인덱싱 을 참조하십시오 .


20

팬더는 비트 단위 '&' '|'를 사용합니다. 각 조건은 '()'

예를 들어 다음 작품

data_query = data[(data['year'] >= 2005) & (data['year'] <= 2010)]

그러나 적절한 대괄호가없는 동일한 쿼리는 그렇지 않습니다.

data_query = data[(data['year'] >= 2005 & data['year'] <= 2010)]

8

또는 운영자 모듈을 사용할 수도 있습니다. 더 자세한 정보는 여기 파이썬 문서

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

1

이 훌륭한 답변 은 무슨 일이 일어나고 있는지 잘 설명하고 해결책을 제공합니다. 비슷한 경우에 적합한 다른 솔루션을 추가하고 싶습니다 : query메소드 사용 :

result = result.query("(var > 0.25) or (var < -0.25)")

http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query 도 참조 하십시오 .

(현재 작업중 인 데이터 프레임을 사용한 일부 테스트는이 방법이 일련의 부울에서 비트 연산자를 사용하는 것보다 약간 느리다는 것을 제안합니다 : 2 ms 대 870 µs

경고 : 간단하지 않은 적어도 하나의 상황은 열 이름이 파이썬 표현식이되는 경우입니다. 나는 열 이름을 가지고 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

쿼리 파서가 세 번째 열의 이름으로 식을 식별하는 대신 처음 두 열에서 무언가를 만들려고했기 때문에 이것이 발생했다고 생각합니다.

가능한 해결 방법이 여기 에 제안 됩니다 .


1

동일한 오류가 발생하여 며칠 동안 pyspark 데이터 프레임으로 중단 되었습니다 .2 필드의 정수 값을 비교했기 때문에 na 값을 0으로 채워서 성공적으로 해결할 수있었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.