यह overkill हो सकता है और अपनी टिप्पणी
दोनों सैद्धांतिक घटता और डेटा बिंदुओं पर आधारित है अलग लंबाई की सरणियों कर रहे हैं।
मैं निम्नलिखित करना होगा:
- डेटा सेट काटें ताकि उसके एक्स मूल्यों अधिकतम और सैद्धांतिक सेट के न्यूनतम मूल्यों के भीतर झूठ बोलते हैं।
scipy.interpolate.interp1d
और उपरोक्त कटा हुआ डेटा x मानों का उपयोग करके सैद्धांतिक वक्र को इंटरपोलेट करें। चरण (1) का कारण interp1d
की बाधाओं को पूरा करना है।
- स्वीकार्य सिद्धांत मूल्यों की सीमा के बाहर डेटा वाई मानों को खोजने के लिए
numpy.where
का उपयोग करें।
- टिप्पणियों और अन्य उत्तरों में सुझाए गए अनुसार इन मानों को त्यागें। यदि आप स्पष्टता चाहते हैं, तो 'इनलाइनर्स' को एक रंग और 'आउटलायर' को अन्य रंगों की साजिश करके उन्हें इंगित करें।
यहां एक ऐसी स्क्रिप्ट है जो आप ढूंढ रहे हैं उसके करीब है, मुझे लगता है। यह उम्मीद है कि मदद मिलेगी आप पूरा आप क्या चाहते हैं:
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')
यह आंकड़ा परिणाम है:
बस एक वैज्ञानिक दृष्टिकोण से पूरी तरह से, मैं बिंदुओं को तब तक नहीं हटाऊंगा जब तक कि कोई स्पष्ट मान्य कारण न हो कि आपको लगता है कि वे गलत हैं। आपके पास पर्याप्त डेटा है कि बाहरी बिंदुओं पर फिट पर कोई प्रभाव नहीं पड़ेगा, इसलिए उन्हें हटाने से केवल ग्राफ को किसी भी वैज्ञानिक उद्देश्य की सेवा किए बिना सुंदर दिखने में मदद मिलती है। – NickLH
आप सही हैं, लेकिन मुझे बताया गया था। –