模式识别1d数据

时间:2017-03-26 09:57:27

标签: python algorithm pattern-recognition

我想在某些光谱中找到模式。 Spectrum image

图片上的灰色圆圈图案应该看起来像2,所有数据看起来都相似。浅蓝色线条是原始数据,点缀深蓝色线条 - 平均超过6个点。我试图做一些大小的窗口和扫描数据,并检查y-flux值是否下降/上升到60以下ish%,但这似乎找到了其他区域和我想要的那个,或者只是我不想要的。

模式的宽度在我所拥有的光谱中并不总是相同的。有一张带有图案黑色虚线的光谱图片,但我的程序没有找到它。

not found picture

我尝试改变窗口大小,但没有帮助。我可以使用一些模式识别算法来找到这种模式吗?有人能指点我吗?或者以简单的方式解释,因为我有点迷失在这,请?

这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
from astropy.io import ascii
import glob

def reading(file_name):
    data = ascii.read(file_name)
    lam = data['col0'][1:-1]
    #data offset *10**17 + 5
    flux = data['col1'][1:-1]*10**17 + 5

    return lam, flux

def percentChange(startPoint,currentPoint):

    return abs(((currentPoint-startPoint)/startPoint))*100.00

def window(data, size):   
    n = len(data)
    out = []   
    wind = data[0 : size]
    i = size    

    while i + size/2 < n:
        wind = data[i - size/2 : i + size/2]
        tmp = percentChange(wind[0], wind[-1])

        if tmp > 50.:
            out.append([tmp, i - size/2, i + size/2])
        i = i + size

    return out

def window2(data, size):

    n = len(data)
    out = []   
    wind = data[0 : size]
    i = size    

    while i + size/2 < n:
        wind = data[i - size/2 : i + size/2]
        tmp = percentChange(wind[0], wind[len(wind)/2])

        if tmp > 50.:
            out.append([tmp, i - size/2, i + size/2])
        i = i + size

    return out

def plotting(lamb, flux):
    plt.rcParams['font.family'] = 'freeserif'
    plt.rcParams['font.size'] = 12
    plt.rcParams['axes.labelsize'] = 15
    plt.rcParams['xtick.labelsize'] = 12
    plt.rcParams['ytick.labelsize'] = 12
    plt.rcParams['legend.fontsize'] = 12
    plt.rcParams['figure.titlesize'] = 12 
    plt.rcParams['xtick.minor.visible'] = True
    plt.rcParams['ytick.minor.visible'] = True

    plt.plot(lamb, flux)
    plt.xlabel("wavelenght [A]")
    plt.ylabel("flux [erg/cm^2/s/A]")

def averaging(lamb, flux, param):
    end = 1480
    bin_flux_1 = [np.mean(flux[i : i + param]) for i in range(0, end, param)]
    bin_lam_1 = [np.mean(lamb[i : i + param]) for i in range(0, end, param)]

    return bin_lam_1, bin_flux_1


def main():

    param = 6
    stack = 6

    for name in glob.glob('TRAIN/*.dat'):
        print name
        lamb, flux = reading(name)
        lamb_a, flux_a = averaging(lamb, flux, param)

        plotting(lamb, flux)
        plotting(lamb_a, flux_a)

        change = window(flux_a, stack)
        change2 = window2(flux_a, stack)

        minim = flux_a.index(min(flux_a))

        for i in range(len(change)):
            plt.axvline(lamb_a[change[i][1]], color='r', linestyle='--',linewidth=1)
            plt.axvline(lamb_a[change[i][2]], color='r', linestyle='--',linewidth=1)
        for i in range(len(change2)):
            plt.axvline(lamb_a[change2[i][1]], color='y', linestyle='-',linewidth=1)
            plt.axvline(lamb_a[change2[i][2]], color='y', linestyle='-',linewidth=1)
        plt.axvline(lamb_a[minim], color='k', linestyle='--',linewidth=1)
        plt.show()    


if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:0)

你可以在线性O(n + m)时间复杂度中使用Knuth-Morris-Pratt算法,其中nm是文本和模式的长度。

KMP算法基本上是一种模式匹配算法(在大海捞针中查找针的起始位置),该算法适用于字符串。

def kmp_matcher(t, d):
    n=len(t)
    m=len(d)

    pi = compute_prefix_function(d)
    q = 0
    i = 0
    while i < n:
        if d[q]==t[i]:
            q=q+1
            i = i + 1
        else:
            if q != 0:
                q = pi[q-1]
            else:
                i = i + 1
        if q == m:
            print "pattern occurs with shift "+str(i-q)
            q = pi[q-1]

def compute_prefix_function(p):
    m=len(p)
    pi =range(m)
    k=1
    l = 0
    while k < m:
        if p[k] <= p[l]:
            l = l + 1
            pi[k] = l
            k = k + 1
        else:
            if l != 0:
                l = pi[l-1]
            else:
                pi[k] = 0
                k = k + 1
    return pi

t = 'brownfoxlazydog'
p = 'lazy'
kmp_matcher(t, p)