2011-10-31 14 views
6

ile bir eğri altında kaldırın. Bazı teorik verileri python'daki gerçek verilerle karşılaştırmalıyım. Teorik veriler bir denklemin çözümlenmesinden kaynaklanır. Karşılaştırmayı geliştirmek için teorik eğriden uzak veri noktalarını kaldırmak istiyorum. Yani, aşağıdaki noktaları (ve matplotlib ile yapılan) kırmızı kesikli çizgileri yukarıda kaldırmak istiyorum. Data points and theoretical curvesVeri noktalarını python

Hem teorik eğriler hem de veri noktaları farklı uzunluktaki dizilerdir.

Ben örneğin, bir kabaca göz şekilde noktalarını kaldırmak için deneyebilirsiniz: birinci üst noktası kullanılarak tespit edilebilir:

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')])  

Ama az kabaca göz yolu kullanmak istiyorum.

Bu yüzden, sorunlu noktaları çıkarmanın kolay bir yolunu bulmama yardımcı olan var mı?

Teşekkür ederiz!

+18

Sadece bilimsel açıdan bakıldığında, yanlış olduklarını düşündüğünüzden aşırı bir geçerli sebep olmadıkça puanları kaldırmayacağım. Dışarıdaki noktaların fit üzerinde herhangi bir etkisi olmayacak kadar yeterli veriye sahip olursunuz, bu yüzden bunları kaldırmak, yalnızca bilimsel bir amaç göstermeden grafiğin güzel görünmesini sağlar. – NickLH

+0

Haklısın, ama bana söylendi. –

cevap

1

Kırmızı eğri ile kesikli kırmızı eğri arasındaki farktan daha büyükse, kırmızı eğri ile noktalar arasındaki farka dikkat edin.

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

Ama lütfen NickLH'den gelen yorumu alın. Verileriniz herhangi bir filtreleme olmadan oldukça iyi görünüyor, "aykırılıklarınız" ın hepsi çok büyük bir hataya sahip ve çok fazla uymayacak.

+1

Bu iyi bir ide, ancak her iki dizinin farklı uzunlukları olduğundan, kırmızı eğri ve noktalar arasındaki farkı hesaplamayı zor buluyorum. Nokta dizisi uzunluğuna sahip kırmızı bir eğri dizisi oluşturmak için enterpolasyon kullanılabilir. –

+0

Red_curves, muhtemelen bir işleve sahip, ancak sadece onunla ilgili x değerleri. – tillsten

4

Bu overkill olabilir ve yorum

teorik eğriler ve veri noktaları Hem dayanmaktadır farklı uzunlukta dizilerdir.

ı aşağıdakileri: bunun x değeri maksimum teorik kümesinin en az değerler arasında yer alacak kadar

  1. set veri kesin.
  2. scipy.interpolate.interp1d ve yukarıdaki kesilmiş veri x değerlerini kullanarak teorik eğriyi enterpole edin. Adım (1) 'in nedeni, interp1d sınırlamalarını karşılamaktır.
  3. numpy.where kullanın ve kabul edilebilir teorik değerler aralığının dışında kalan verileri bulun.
  4. DONT bu değerleri, yorumlar ve diğer cevaplarda önerildiği gibi atmaz. Netlik istiyorsanız, 'inlin' bir rengi ve 'aykırı' bir başka rengi çizerek onları işaretleyin.

İşte aradığınız şeye yakın bir komut dosyası, bence. Bu umarım yardımcı olacaktır istediğini başarmak:

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

Bu rakam sonucudur: enter image description here

0

Ya(), xy çiftleri senin komplo kriterlere uygun olduğunu belirlemek için numpy.where kullanabilir veya belki de hemen hemen aynı şeyi yapmak için numaralandırır.Örnek:

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 

O '2' ve '5' yukarıdaki örnekte sizin eğrilerin işlevlerini; bu nedenle koşulları değişebilir eminim

sonunda
4

Ben Yann bazılarını kullanmak kod:

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 

bu işlevleri kullanma sonunda elde edebilirsiniz:

Data selection

Yardımlarınız için hepinize teşekkür ederim.

+2

+1 Bize çözümünüzü göstermek ve aynı zamanda dışarıdaki noktaları grafik üzerinde tutmak için. – NickLH

İlgili konular