2017-11-17 6 views
2

다음과 같은 곡선을 생성하는 데이터 및 시간 지점이 있습니다.기울기가 변경되는 곡선에서 위치 찾기

time 데이터

array([ 0.10810811, 0.75675676, 1.62162162, 2.59459459, 
     3.56756757, 4.21621622, 4.97297297, 4.97297297, 
     4.97297297, 4.97297297, 4.97297297, 4.97297297, 
     4.97297297, 4.97297297, 5.08108108, 5.18918919, 
     5.2972973 , 5.51351351, 5.72972973, 5.94594595, 
     6.27027027, 6.59459459, 7.13513514, 7.67567568, 
     8.32432432, 9.18918919, 10.05405405, 10.91891892, 
     11.78378378, 12.64864865, 13.51351351, 14.37837838, 
     15.35135135, 16.32432432, 17.08108108, 18.16216216, 
     19.02702703, 20.  , 20.  , 20.  , 
     20.  , 20.  , 20.  , 20.  , 
     20.10810811, 20.21621622, 20.43243243, 20.64864865, 
     20.97297297, 21.40540541, 22.05405405, 22.91891892, 
     23.78378378, 24.86486486, 25.83783784, 26.7027027 , 
     27.56756757, 28.54054054, 29.51351351, 30.48648649, 
     31.56756757, 32.64864865, 33.62162162, 34.59459459, 
     35.67567568, 36.64864865, 37.62162162, 38.59459459, 
     39.67567568, 40.75675676, 41.83783784, 42.81081081, 
     43.89189189, 44.97297297, 46.05405405, 47.02702703, 
     48.10810811, 49.18918919, 50.27027027, 51.35135135, 
     52.43243243, 53.51351351, 54.48648649, 55.56756757, 
     56.75675676, 57.72972973, 58.81081081, 59.89189189]) 

이고 volts 데이터 I는 A, B, C, D로 표시된 점의 위치를 ​​확인하고자

array([ 4.11041056, 4.11041056, 4.11041056, 4.11041056, 4.11041056, 
     4.11041056, 4.11041056, 4.10454545, 4.09794721, 4.09208211, 
     4.08621701, 4.07961877, 4.07228739, 4.06568915, 4.05909091, 
     4.05175953, 4.04516129, 4.03782991, 4.03123167, 4.02463343, 
     4.01803519, 4.01217009, 4.00557185, 3.99970674, 3.99384164, 
     3.98797654, 3.98284457, 3.97771261, 3.97331378, 3.96891496, 
     3.96451613, 3.96085044, 3.95645161, 3.95205279, 3.9483871 , 
     3.94398827, 3.94032258, 3.93665689, 3.94325513, 3.94985337, 
     3.95645161, 3.96378299, 3.97038123, 3.97624633, 3.98284457, 
     3.98944282, 3.99604106, 4.0026393 , 4.00923754, 4.01510264, 
     4.02096774, 4.02609971, 4.02903226, 4.03196481, 4.03416422, 
     4.0356305 , 4.03709677, 4.03856305, 4.03929619, 4.04002933, 
     4.04076246, 4.04222874, 4.04296188, 4.04296188, 4.04369501, 
     4.04442815, 4.04516129, 4.04516129, 4.04589443, 4.04589443, 
     4.04662757, 4.04662757, 4.0473607 , 4.0473607 , 4.04809384, 
     4.04809384, 4.04809384, 4.04882698, 4.04882698, 4.04882698, 
     4.04956012, 4.04956012, 4.04956012, 4.04956012, 4.05029326, 
     4.05029326, 4.05029326, 4.05029326]) 

plot of the curve

인 , E. Point A는 기울기가 0에서 정의되지 않은 첫 번째 위치입니다. 점 B는 선이 더 이상 수직이 아닌 위치입니다. 점 C는 곡선의 최소값입니다. 점 D는 곡선이 더 이상 수직이 아닌 곳입니다. 점 E는 기울기가 다시 0에 가까워지는 지점입니다. 파이썬 코드에서는 I는 점 B, D 및 E로 표시되는 곡선상의 다른 위치를 확인하는 방법을 점 A의 위치 및 C.

tdiff = np.diff(time) 
vdiff = np.diff(volts) 

# point A 
idxA = np.where(vdiff < 0)[0][0] 
timeA = time[idxA] 
voltA = volts[idxA] 

# point C 
idxC = volts.idxmin() 
timeC = time[idxC] 
voltC = volts[idxC] 

plot with points A and C

결정?

+4

포인트는 어떻게 결정됩니까? 당신은 당신이하고자하는 것에 대한 명확한 정의 나 데이터를 제공하지 않습니다. "변곡점"이라는 단어를 사용하면 실제로 원하는 것을 명확하게 정의하지 않으면 아무 것도 도움이되지 않습니다. 그 점들은 수학 변곡점처럼 보이지 않습니다. –

+1

팬더 커뮤니티에 올 때 일부 데이터가있는 것을 잊지 마십시오. 데이터가 해답을 결정합니다. – Dark

+0

그런 점에 대해 특별한 점은 무엇입니까? 그 질문에 대한 자세한 내용을 편집하십시오. 당신이 올바르게한다면, 당신은 아마도 자신의 질문에 대답 할 수있을 것입니다. –

답변

5

기울기가 0 또는 무한대로 바뀌는 위치를 표시하는 점을 찾고 있습니다. 슬로프는 실제로 yn - yn-1 == 0yn+1 - yn != 0 중 하나 또는 그 반대로 계산하거나 x과 동일하게 계산할 필요가 없습니다.

차이점은 x입니다. 두 개의 연속 요소 중 하나가 0이면 diff의 diff는 해당 시점의 diff 또는 negative diff입니다. 그래서 우리는 단지 배열의 크기 차이에 맞게 적절하게 조정 된 diff(x) == diff(diff(x))diff(x) != 0을 찾아서 레이블을 붙이고 싶습니다. 우리는 또한 y에 대해 똑같은 모든 포인트를 원합니다. NumPy와 측면에서

,

def masks(vec): 
    d = np.diff(vec) 
    dd = np.diff(d) 

    # Mask of locations where graph goes to vertical or horizontal, depending on vec 
    to_mask = ((d[:-1] != 0) & (d[:-1] == -dd)) 
    # Mask of locations where graph comes from vertical or horizontal, depending on vec 
    from_mask = ((d[1:] != 0) & (d[1:] == dd)) 
    return to_mask, from_mask 

to_vert_mask, from_vert_mask = masks(time) 
to_horiz_mask, from_horiz_mask = masks(volts) 

는 마스크 2 차 차이를 산출하고 있다는 사실을 숙지 이것은 다음과 같이 작성 될 수있다, 그래서 입력보다 짧은 두 가지 요소이다. 마스크의 요소는 입력 배열의 요소에 해당하며 앞과 뒤쪽 가장자리에 한 요소 테두리가 있습니다 (따라서 색인 [1:-1] 아래). 당신은 np.nonzero를 사용하여 인덱스에 마스크를 변환 할 수 있습니다 또는 당신은 x 축과 직접 인덱스로 마스크를 사용하여 y 값 얻을 수 있습니다 :

enter image description here

공지 사항 : 여기

def apply_mask(mask, x, y): 
    return x[1:-1][mask], y[1:-1][mask] 

to_vert_t, to_vert_v = apply_mask(to_vert_mask, time, volts) 
from_vert_t, from_vert_v = apply_mask(from_vert_mask, time, volts) 
to_horiz_t, to_horiz_v = apply_mask(to_horiz_mask, time, volts) 
from_horiz_t, from_horiz_v = apply_mask(from_horiz_mask, time, volts) 

plt.plot(time, volts, 'b-') 
plt.plot(to_vert_t, to_vert_v, 'r^', label='Plot goes vertical') 
plt.plot(from_vert_t, from_vert_v, 'kv', label='Plot stops being vertical') 
plt.plot(to_horiz_t, to_horiz_v, 'r>', label='Plot goes horizontal') 
plt.plot(from_horiz_t, from_horiz_v, 'k<', label='Plot stops being horizontal') 
plt.legend() 
plt.show() 

이 결과 플롯이다 분류가 개별적으로 수행되기 때문에 "점 A"는 수직이 시작되고 수평이 끝나는 지점으로 올바르게 식별됩니다. 문제는 "기준점 E"가 이러한 기준에 따라 해석 될 수없는 것입니다.확대하면 증식 된 모든 점이 제대로 수평 라인 세그먼트를 식별 있음을 보여줍니다

enter image description here

을 완전히 from_horiz을 버리고 "포인트 E"의 "올바른"버전을 선택하고 수

to_horiz에서 마지막 값 :

to_horiz_t, to_horiz_v = apply_mask(to_horiz_mask, time, volts) 
to_horiz_t, to_horiz_v = to_horiz_t[-1], to_horiz_v[-1] 

plt.plot(time, volts, 'b-') 
plt.plot(*apply_mask(to_vert_mask, time, volts), 'r^', label='Plot goes vertical') 
plt.plot(*apply_mask(from_vert_mask, time, volts), 'kv', label='Plot stops being vertical') 
plt.plot(to_horiz_t, to_horiz_v, 'r>', label='Plot goes horizontal') 
plt.legend() 
plt.show() 

나는 apply_mask의 결과의 스타 확장을위한 쇼케이스로 이것을 사용하고 있습니다. 결과 플롯은 다음과 같습니다

enter image description here

이 당신이 찾고 있던 거의 정확하게 플롯이다. from_horiz을 버리면 "Point A"가 수직으로 떨어지는 것으로 만 식별됩니다.

to_horiz의 값이 여러 개인 경우이 방법은 데이터 내의 노이즈에 매우 민감합니다. 데이터는 매우 부드럽지만이 방법은 필터링되지 않은 원시 측정을 사용하지 않을 것입니다.

+0

심층 답변을 가져 주셔서 감사합니다. – wigging

+0

@ wigging. 네가 좋다 니 기쁘다. 나는 조금 더 깨끗하게 보이기 위해 그림을 업데이트했다. –