2016-04-28 7 views
63

का उपयोग करें या परिणाम के साथ मेरा परिणाम डेटाफ्रेम फ़िल्टर करना जारी रखें। मैं अपने परिणाम डीएफ को सभी कॉलम var मानों को निकालने के लिए चाहता हूं जो 0.25 से ऊपर और नीचे -0.25 से ऊपर हैं। नीचे यह तर्क मुझे एक अस्पष्ट सत्य मूल्य देता है हालांकि यह तब होता है जब मैं इस फ़िल्टरिंग को दो अलग-अलग परिचालनों में विभाजित करता हूं। यहाँ क्या हो रहा है? सुनिश्चित नहीं है कि सुझाए गए a.empty(), a.bool(), a.item(), a.any() या a.all() का उपयोग करना है।एक श्रृंखला का वास्तविक मूल्य संदिग्ध है। A.empty, a.bool(), a.item(), a.any() या a.all()

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

आपको और संदर्भ जोड़ना चाहिए। मुझे समझ में नहीं आता कि परिणाम क्या है और आप क्या करने की कोशिश कर रहे हैं। – kingledion

+5

'या' – MaxU

उत्तर

121

or और and अजगर बयान truth -values ​​आवश्यकता होती है। pandas के लिए इन अस्पष्ट माना जाता है तो आप "बिटवाइज़" | (या) या & (और) के संचालन का उपयोग करना चाहिए:

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

ये उपज के लिए datastructures के इन प्रकार के लिए अतिभारित रहे हैं तत्व के लिहाज से or (या and) ।


बस इस बयान के लिए कुछ और स्पष्टीकरण जोड़ने के लिए:

अपवाद फेंक दिया जाता है जब आप boolpandas.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,के लिए भी होता हैऔर 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 
    

आप ऑपरेटर्स का उपयोग कर रहे हैं तो सुनिश्चित करें कि आप the operator precedence की वजह से सही ढंग से अपने कोष्ठकों सेट किया है।

several logical numpy functionspandas.Series पर काम करना चाहिए।


विकल्प अपवाद में उल्लेख किया है और अधिक अनुकूल जब if या while कर अगर आप इसे का सामना करना पड़ा है। मैं शीघ्र ही इनमें से प्रत्येक समझाएंगे:

  • आप जाँच करना चाहते हैं, तो आपके सीरीज खाली है:

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

    अजगर सामान्य रूप से कंटेनरों की len gth की व्याख्या (जैसे list, tuple, ...) सत्य-मूल्य के रूप में यदि इसमें कोई स्पष्ट बूलियन व्याख्या नहीं है। तो यदि आप पाइथन जैसी जांच चाहते हैं, तो आप if x के बजाय if x.size या if not x.empty कर सकते हैं।

  • अपने Seriesएक और केवल एक बूलियन मान शामिल हैं:

    >>> x = pd.Series([100]) 
    >>> (x > 50).bool() 
    True 
    >>> (x < 50).bool() 
    False 
    
  • आप अपनी श्रृंखला के पहली और एकमात्र आइटम जाँच करना चाहते हैं (जैसे .bool() नहीं बल्कि बूलियन के लिए भी काम करता है सामग्री):

    >>> x = pd.Series([100]) 
    >>> x.item() 
    100 
    
  • आप अगर एक जाँच करना चाहते हैं ll या किसी भी आइटम नहीं-शून्य है, नहीं खाली या नहीं-गलत:

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

के बजाय '|' का उपयोग करें हे भगवान! आपकी टिप्पणी "यदि आप ऑपरेटरों का उपयोग कर रहे हैं तो सुनिश्चित करें कि ऑपरेटर की प्राथमिकता के कारण आप अपने कोष्ठक को सही ढंग से सेट करते हैं" अंततः मुझे पागल गाड़ी चला रही समस्या हल हो गई। एक बहुत ही महत्वपूर्ण और, मेरे मामले में, अनदेखा बिंदु। धन्यवाद! – user4896331

+2

मैंने सबसे लंबे समय तक पढ़े गए सबसे अधिक जानकारीपूर्ण उत्तरों में से एक है – deadcode

15

बूलियन तर्क के लिए, & और | का उपयोग करें।

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 को देखें।

2

या, वैकल्पिक रूप से, आप ऑपरेटर मॉड्यूल का उपयोग कर सकते हैं। अधिक विस्तृत जानकारी Python docs

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 
0

This excellent answer बहुत अच्छी तरह से क्या हो रहा है बताते हैं और एक समाधान प्रदान करता यहाँ है। query विधि का उपयोग कर:: मैं एक और समाधान है कि इसी तरह के मामलों में उपयुक्त हो सकता है जोड़ना चाहते हैं

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

भी देखें http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query

(कुछ एक dataframe मैं वर्तमान के साथ काम कर रहा हूँ के साथ परीक्षण का सुझाव है कि इस विधि थोड़ा बूलियन्स की श्रृंखला पर बिटवाइज़ ऑपरेटर्स का उपयोग कर की तुलना में धीमी: 2 एमएस बनाम 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

मुझे लगता है कि ऐसा हुआ क्योंकि क्वेरी बराबर है सीर तीसरे कॉलम के नाम से अभिव्यक्ति की पहचान करने के बजाय पहले दो कॉलम से कुछ बनाने की कोशिश कर रहा था।

एक संभावित कार्यवाही प्रस्तावित here है।

संबंधित मुद्दे