728x90
반응형
1. 해당 그래프의 y값이 최댓값인 3개를 a점으로 지정하고 각각 a점의 x좌표보다 큰 극소, 극대 값 중 x값이 가까운 순서대로 b, c, d, e를 지정합니다.(b, d는 극소 중에서, c, e는 극대중에서 지정하려 합니다.)
2. 각각 a, b, c, d, e의 x좌표 차이 및 y좌표 차이 구하려 합니다. (a_b_x = a_x - b_x, , , , d_e_y = d_y - e_y 이런 식으로 구하려합니다.) 그 뒤에 a~e점까지 각 3 개씩 존재하니(점이 없는 경우는 0으로 대체) 각각의 a_b_x~d_e_y의 평균을 구하고 엑셀 파일에 넣는 것 까지 하고 싶습니다.
현재 chat gpt를 이용하여 여러번 시도했으나 b~e지점을 지정하는 것부터 난관이라서 어떻게 해야할지 막막합니다. 말로는 설명을 하겠는데 코드로 구현을 하려니 힘드네요. 아래는 현재 작성한 코드와 파일입니다. python 주피터 노트북으로 하고 있습니다. 시간 되시면 확인 후 고견 부탁드립니다. 감사합니다.
(맨위에 import 넣은 것들은 여러 코드를 넣고 빼다 보니 뒤죽박죽하여 일단 같이 두었습니다.)
import pandas as pd
import numpy as np
from scipy.signal import cheby2, filtfilt
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
from scipy.signal import find_peaks
# 텍스트 파일 읽기
filename = "./2_1.txt"
data = np.loadtxt(filename)
# 필터 설계
order = 4 # 필터의 차수
fs = 1000 # 샘플링 주파수
start_freq = 0.4 # 시작 주파수
stop_freq = 8 # 종료 주파수
Wn = [start_freq / (fs /3), stop_freq / (fs / 3)] # 시작 주파수와 종료 주파수 계산 및 정규화
rs = 30 # 정지대역 감쇠
b, a = cheby2(order, rs, Wn, 'bandpass') # Chebyshev 2 필터 설계
# 필터 적용
PPG = filtfilt(b, a, data)
VPG = np.diff(PPG)
VPG_filtered_data = filtfilt(b, a, VPG)
APG = np.diff(VPG_filtered_data)
APG_filtered_data = filtfilt(b, a, APG)
plt.plot(APG_filtered_data, label='APG')
# 극댓값의 인덱스와 값을 구함
maxima_indices = argrelextrema(APG_filtered_data, np.greater)[0]
maxima_values = APG_filtered_data[maxima_indices]
# 극소값의 인덱스와 값을 구함
minima_indices = argrelextrema(APG_filtered_data, np.less)[0]
minima_values = APG_filtered_data[minima_indices]
plt.plot(maxima_indices, APG_filtered_data[maxima_indices], 'ro', label='Local Maxima')
plt.plot(minima_indices, APG_filtered_data[minima_indices], 'bo', label='Local Minima')
plt.legend()

요청 내용 중 'y값이 최댓값인 3개를 a점'을 이해하지 못해서 y 값이 최대값일때를 a로 했습니다.
maxima_indices, maxima_value를 보면

a 즉 최고점을 찾기 위해 다음과 같이 합니다.

최고점의 값으로 인덱스를 찾습니다.

다음과 같이 위 작업을 한 줄로 만듭니다.
a_idx = int(np.where(maxima_values == np.max(maxima_values))[0])
a를 중심으로 a의 x 뒤로 4개를 b,c,d,e로 하니 다음과 같이 인덱스를 사용하면 됩니다.
a,b,c,d,e의 값이 됩니다.
abcde_value = maxima_values[a_idx:a_idx + 6].tolist()
abcde_value

a,b,c,d,e 인덱스 구합니다.
abcde_lst = maxima_indices[a_idx:a_idx + 6].tolist()
abcde_lst

계산을 위해 설면하자면 다음과 같이 a_x 등의 값을 지정해서 계산하면 됩니다.
# a_b_x = a_x - b_x
a_x = maxima_indices[a_idx]
b_x = maxima_indices[a_idx+1]
c_x = maxima_indices[a_idx+2]
d_x = maxima_indices[a_idx+3]
e_x = maxima_indices[a_idx+4]
a_b_x = a_x - b_x
print(a_b_x)
엑셀에 쓰는 것까지 생각해서 딕셔너리로 결과를 만듭니다.
result = {}
for i in range(1, len(abcde_lst)):
for j in range(i, len(abcde_lst)):
result[f'{i}_{j}'] = [abcde_lst[i-1] - abcde_lst[j], abcde_value[i-1] - abcde_value[j]]
print(result)
다음과 같이 계산 결과 딕셔너리가 만들어 집니다.
key가 어떤 값들이 계산된 것인지가 되고, 딕셔너리의 value는 리스트로 0은 x의 계산, 1은 y의 계산이 됩니다.
{'1_1': [-252, 0.06413291491479274]
, '1_2': [-436, 0.1289774126753518]
, '1_3': [-607, 0.02257596641367092]
, '1_4': [-842, 0.082292478475908]
, '2_2': [-184, 0.06484449776055903]
, '2_3': [-355, -0.04155694850112182]
, '2_4': [-590, 0.018159563561115255]
, '3_3': [-171, -0.10640144626168085]
, '3_4': [-406, -0.046684934199443785]
, '4_4': [-235, 0.059716512062237076]}
다음과 같이 엑셀 저장을 만듭니다.
from openpyxl import Workbook
write_wb = Workbook()
# for i, key, value in enumerate(result.items()):
write_ws = write_wb.active
i = 1
for key, value in result.items():
print(i, key, value)
write_ws.cell(i, 2, key)
write_ws.cell(i, 3, value[0])
write_ws.cell(i, 4, value[1])
i += 1
write_wb.save('max_minima.xlsx')
728x90
반응형
'프로그램' 카테고리의 다른 글
| [파이썬] 주피터노트북 실행 아이콘 만들기(가상환경) (0) | 2023.07.28 |
|---|---|
| [파이썬] 작업스케줄러 사용 (0) | 2023.07.28 |
| [파이썬] 사인파 곡선에서 최저, 최고점 찾기 (scipy, argrelextrema) (0) | 2023.07.27 |
| [파이썬] tensorflow로 GPU 상태(메모리 등) 확인하기 (0) | 2023.07.21 |
| [파이썬] Flask를 사용해 웹서버 만들기 (외부에서 접속하기) (0) | 2023.07.19 |


댓글