2011-10-31 3 views
6

के साथ वक्र के नीचे डेटा बिंदुओं को निकालें मुझे कुछ सैद्धांतिक डेटा की तुलना पाइथन में वास्तविक डेटा के साथ करने की आवश्यकता है। सैद्धांतिक डेटा एक समीकरण को हल करने से आता है। तुलनात्मक सुधारने के लिए मैं सैद्धांतिक वक्र से दूर डेटा बिंदुओं को हटाना चाहता हूं। मेरा मतलब है, मैं आकृति में लाल धराशायी रेखाओं के नीचे और ऊपर के बिंदुओं को हटाना चाहता हूं (matplotlib के साथ बनाया गया)। Data points and theoretical curvesपायथन

सैद्धांतिक घटता और डेटा बिंदु दोनों अलग-अलग लंबाई के सरणी हैं।

मैं उदाहरण के लिए, एक मोटे तौर पर आँख तरह से अंक दूर करने की कोशिश कर सकते हैं: पहला ऊपरी बिंदु का उपयोग कर पता लगाया जा सकता:

data2[(data2.redshift<0.4)&data2.dmodulus>1] 
rec.array([('1997o', 0.374, 1.0203223485103787, 0.44354759972859786)], dtype=[('SN_name', '|S10'), ('redshift', '<f8'), ('dmodulus', '<f8'), ('dmodulus_error', '<f8')])  

लेकिन मैं एक कम मोटे तौर पर आँख तरीके से उपयोग करना चाहते हैं।

तो, क्या कोई मुझे समस्याग्रस्त बिंदुओं को हटाने का आसान तरीका खोजने में मदद कर सकता है?

धन्यवाद!

+18

बस एक वैज्ञानिक दृष्टिकोण से पूरी तरह से, मैं बिंदुओं को तब तक नहीं हटाऊंगा जब तक कि कोई स्पष्ट मान्य कारण न हो कि आपको लगता है कि वे गलत हैं। आपके पास पर्याप्त डेटा है कि बाहरी बिंदुओं पर फिट पर कोई प्रभाव नहीं पड़ेगा, इसलिए उन्हें हटाने से केवल ग्राफ को किसी भी वैज्ञानिक उद्देश्य की सेवा किए बिना सुंदर दिखने में मदद मिलती है। – NickLH

+0

आप सही हैं, लेकिन मुझे बताया गया था। –

उत्तर

1

लाल वक्र और बिंदुओं के बीच अंतर को देखें, यदि यह लाल वक्र के बीच अंतर से बड़ा है और धराशायी लाल वक्र इसे हटा दें।

diff=np.abs(points-red_curve) 
index= (diff>(dashed_curve-redcurve)) 
filtered=points[index] 

लेकिन कृपया निकल गंभीर से टिप्पणी लें। आपका डेटा किसी फ़िल्टरिंग के बिना बहुत अच्छा दिखता है, आपके "आउटलेटर्स" में बहुत बड़ी त्रुटि होती है और इससे काफी प्रभावित नहीं होगा।

+1

यह एक अच्छा विचार है, लेकिन मुझे लाल वक्र और बिंदुओं के बीच अंतर की गणना करना मुश्किल लगता है, क्योंकि दोनों सरणीओं की अलग-अलग लंबाई होती है। कोई अंक सरणी लंबाई के साथ लाल वक्र सरणी बनाने के लिए इंटरपोलेट का उपयोग कर सकता है। –

+0

red_curves शायद एक फ़ंक्शन के साथ बनाए गए हैं, लेकिन इसमें शेष एक्स-मान हैं। – tillsten

4

यह overkill हो सकता है और अपनी टिप्पणी

दोनों सैद्धांतिक घटता और डेटा बिंदुओं पर आधारित है अलग लंबाई की सरणियों कर रहे हैं।

मैं निम्नलिखित करना होगा:

  1. डेटा सेट काटें ताकि उसके एक्स मूल्यों अधिकतम और सैद्धांतिक सेट के न्यूनतम मूल्यों के भीतर झूठ बोलते हैं।
  2. scipy.interpolate.interp1d और उपरोक्त कटा हुआ डेटा x मानों का उपयोग करके सैद्धांतिक वक्र को इंटरपोलेट करें। चरण (1) का कारण interp1d की बाधाओं को पूरा करना है।
  3. स्वीकार्य सिद्धांत मूल्यों की सीमा के बाहर डेटा वाई मानों को खोजने के लिए numpy.where का उपयोग करें।
  4. टिप्पणियों और अन्य उत्तरों में सुझाए गए अनुसार इन मानों को त्यागें। यदि आप स्पष्टता चाहते हैं, तो 'इनलाइनर्स' को एक रंग और 'आउटलायर' को अन्य रंगों की साजिश करके उन्हें इंगित करें।

यहां एक ऐसी स्क्रिप्ट है जो आप ढूंढ रहे हैं उसके करीब है, मुझे लगता है। यह उम्मीद है कि मदद मिलेगी आप पूरा आप क्या चाहते हैं:

import numpy as np 
import scipy.interpolate as interpolate 
import matplotlib.pyplot as plt 

# make up data 
def makeUpData(): 
    '''Make many more data points (x,y,yerr) than theory (x,y), 
    with theory yerr corresponding to a constant "sigma" in y, 
    about x,y value''' 
    NX= 150 
    dataX = (np.random.rand(NX)*1.1)**2 
    dataY = (1.5*dataX+np.random.rand(NX)**2)*dataX 
    dataErr = np.random.rand(NX)*dataX*1.3 
    theoryX = np.arange(0,1,0.1) 
    theoryY = theoryX*theoryX*1.5 
    theoryErr = 0.5 
    return dataX,dataY,dataErr,theoryX,theoryY,theoryErr 

def makeSameXrange(theoryX,dataX,dataY): 
    ''' 
    Truncate the dataX and dataY ranges so that dataX min and max are with in 
    the max and min of theoryX. 
    ''' 
    minT,maxT = theoryX.min(),theoryX.max() 
    goodIdxMax = np.where(dataX<maxT) 
    goodIdxMin = np.where(dataX[goodIdxMax]>minT) 
    return (dataX[goodIdxMax])[goodIdxMin],(dataY[goodIdxMax])[goodIdxMin] 

# take 'theory' and get values at every 'data' x point 
def theoryYatDataX(theoryX,theoryY,dataX): 
    '''For every dataX point, find interpolated thoeryY value. theoryx needed 
    for interpolation.''' 
    f = interpolate.interp1d(theoryX,theoryY) 
    return f(dataX[np.where(dataX<np.max(theoryX))]) 

# collect valid points 
def findInlierSet(dataX,dataY,interpTheoryY,thoeryErr): 
    '''Find where theoryY-theoryErr < dataY theoryY+theoryErr and return 
    valid indicies.''' 
    withinUpper = np.where(dataY<(interpTheoryY+theoryErr)) 
    withinLower = np.where(dataY[withinUpper] 
        >(interpTheoryY[withinUpper]-theoryErr)) 
    return (dataX[withinUpper])[withinLower],(dataY[withinUpper])[withinLower] 

def findOutlierSet(dataX,dataY,interpTheoryY,thoeryErr): 
    '''Find where theoryY-theoryErr < dataY theoryY+theoryErr and return 
    valid indicies.''' 
    withinUpper = np.where(dataY>(interpTheoryY+theoryErr)) 
    withinLower = np.where(dataY<(interpTheoryY-theoryErr)) 
    return (dataX[withinUpper],dataY[withinUpper], 
      dataX[withinLower],dataY[withinLower]) 
if __name__ == "__main__": 

    dataX,dataY,dataErr,theoryX,theoryY,theoryErr = makeUpData() 

    TruncDataX,TruncDataY = makeSameXrange(theoryX,dataX,dataY) 

    interpTheoryY = theoryYatDataX(theoryX,theoryY,TruncDataX) 

    inDataX,inDataY = findInlierSet(TruncDataX,TruncDataY,interpTheoryY, 
            theoryErr) 

    outUpX,outUpY,outDownX,outDownY = findOutlierSet(TruncDataX, 
                TruncDataY, 
                interpTheoryY, 
                theoryErr) 
    #print inlierIndex 
    fig = plt.figure() 
    ax = fig.add_subplot(211) 

    ax.errorbar(dataX,dataY,dataErr,fmt='.',color='k') 
    ax.plot(theoryX,theoryY,'r-') 
    ax.plot(theoryX,theoryY+theoryErr,'r--') 
    ax.plot(theoryX,theoryY-theoryErr,'r--') 
    ax.set_xlim(0,1.4) 
    ax.set_ylim(-.5,3) 
    ax = fig.add_subplot(212) 

    ax.plot(inDataX,inDataY,'ko') 
    ax.plot(outUpX,outUpY,'bo') 
    ax.plot(outDownX,outDownY,'ro') 
    ax.plot(theoryX,theoryY,'r-') 
    ax.plot(theoryX,theoryY+theoryErr,'r--') 
    ax.plot(theoryX,theoryY-theoryErr,'r--') 
    ax.set_xlim(0,1.4) 
    ax.set_ylim(-.5,3) 
    fig.savefig('findInliers.png') 

यह आंकड़ा परिणाम है: enter image description here

0

या तो आप numpy.where इस्तेमाल कर सकते हैं(), की पहचान करने के जो xy जोड़े अपने साजिश रचने मानदंडों को पूरा या शायद एक ही चीज़ को काफी करने के लिए गणना करें।उदाहरण:

x_list = [ 1, 2, 3, 4, 5, 6 ] 
y_list = ['f','o','o','b','a','r'] 

result = [y_list[i] for i, x in enumerate(x_list) if 2 <= x < 5] 

print result 

मुझे यकीन है कि आप स्थिति को बदल सकता है इतना है कि '2' और '5' ऊपर के उदाहरण में अपने घटता के कार्य हैं हूँ

4

अंत में मैं यान से कुछ का उपयोग कोड:

def theoryYatDataX(theoryX,theoryY,dataX): 
'''For every dataX point, find interpolated theoryY value. theoryx needed 
for interpolation.''' 
f = interpolate.interp1d(theoryX,theoryY) 
return f(dataX[np.where(dataX<np.max(theoryX))]) 

def findOutlierSet(data,interpTheoryY,theoryErr): 
    '''Find where theoryY-theoryErr < dataY theoryY+theoryErr and return 
    valid indicies.''' 

    up = np.where(data.dmodulus > (interpTheoryY+theoryErr)) 
    low = np.where(data.dmodulus < (interpTheoryY-theoryErr)) 
    # join all the index together in a flat array 
    out = np.hstack([up,low]).ravel() 

    index = np.array(np.ones(len(data),dtype=bool)) 
    index[out]=False 

    datain = data[index] 
    dataout = data[out] 

    return datain, dataout 

def selectdata(data,theoryX,theoryY): 
    """ 
    Data selection: z<1 and +-0.5 LFLRW separation 
    """ 
    # Select data with redshift z<1 
    data1 = data[data.redshift < 1] 

    # From modulus to light distance: 
    data1.dmodulus, data1.dmodulus_error = modulus2distance(data1.dmodulus,data1.dmodulus_error) 

    # redshift data order 
    data1.sort(order='redshift') 

    # Outliers: distance to LFLRW curve bigger than +-0.5 
    theoryErr = 0.5 
    # Theory curve Interpolation to get the same points as data 
    interpy = theoryYatDataX(theoryX,theoryY,data1.redshift) 

    datain, dataout = findOutlierSet(data1,interpy,theoryErr) 
    return datain, dataout 

उन कार्यों का उपयोग करते हुए मैं अंत में प्राप्त कर सकते हैं:

Data selection

आपकी मदद के लिए सभी को धन्यवाद।

+2

+1 हमें अपना समाधान दिखाने के लिए और ग्राफ पर बहिष्कृत बिंदुओं को रखने के लिए भी। – NickLH