#python #python-2.7 #nested
#python #python-2.7 #вложенный
Вопрос:
Я использую базу данных Physionet для некоторых задач, связанных с анализом сигналов ЭКГ. Я хотел прочитать.Файлы MAT, извлеките показания MLII из файла (расположены по всей строке 1), отрегулируйте сигнал до mV, используя «усиление» и «база» (расположены в .ИНФОРМАЦИЯ, также предоставленная Physionet) и, наконец, выведите значения сигнала и его период.
Я хотел написать скрипт, который мог бы выполнять все эти действия со всеми файлами в одной папке. До этого я написал ту, в которой я мог делать все, что упоминалось выше, и она работала хорошо.
Но скрипт, который будет управлять всеми файлами .mat и .info в моей папке, вызывает у меня проблемы с переменными. Я попытался использовать команду ‘global’ в самом начале моей последовательности IFS, но она продолжала посылать аналогичное сообщение об ошибке.
Это код:
import os
import scipy.io as sio
import numpy as np
import re
import matplotlib.pyplot as plt
for file in os.listdir('C:blablablablablaMultiple .mat files'):
if file.endswith(".mat"):
file_name=os.path.splitext(file)
ext_txt=".txt"
ext_info=".info"
if file.endswith(".info"):
f=open(file_name[0] ext_info,'r')
k=f.read()
f.close()
j=re.findall('d ', k)
Fs=j[9]
gain=j[13]
base=j[14]
RawData=sio.loadmat(file)
signalVectors=RawData['val']
[a,b]=signalVectors.shape
signalVectors_2=np.true_divide((signalVectors-gain),base)
ecgSignal=signalVectors_2[1,1:]
T=np.true_divide(np.linspace(1,b,num=b-1),Fs)
txt_data=np.array([ecgSignal, T])
txt_data=txt_data.T
f=open(file_name[0] ext_name,'w')
np.savetxt(file_name[0] ext_txt,txt_data,fmt=['%.8f','%.8f'])
f.close()
Я получаю сообщение об ошибке:
> File "C:blablablablablaMultiple .mat filesecg_mat_multi.py", line 24, in <module>
signalVectors_2=np.true_divide((signalVectors-gain),base)
NameError: name 'gain' is not defined
Проблема связана с переменными ‘gain’, ‘base’ и ‘Fs’. Я попытался определить их как глобальные переменные, но это ничего не изменило. Можете ли вы помочь мне исправить эту ошибку, пожалуйста?
Большое спасибо за ваше время и помощь.
РЕДАКТИРОВАТЬ 1: скопировано сообщение об ошибке под скриптом. РЕДАКТИРОВАТЬ 2: изменен заголовок сообщения и удалены дополнительные вопросы.
Комментарии:
1. Вы не сказали нам, в чем ошибка. Какая переменная не определена?
2.вы можете получить частоту, ища строковый индекс слов «Частота дискретизации», а затем просматривая соответствующие символы после, т.е.:
index = your_string.index('Sampling frequency:')
frequency = your_string[(index 20): (index 23)]
3. Если это
if file.endswith(".info")
False
соответствует вашим именам, таким какgain
,base
, и т. Д., Не определены, Потому что они будут инициализированы только в том случае, если это выражение оцениваетсяTrue
как, в некоторых случаях ваша программа пытается обработать файл, который не соответствует этим критериям.4. Не задавайте 3 вопроса сразу. Сосредоточьтесь на одной проблеме.
5. Ошибка, которую вы получаете, связана с тем, что коэффициент усиления ранее не был определен. Причина в том, что условие ‘if’ никогда не выполняется. Таким образом,
file.endswith(".info")
всегда равно False
Ответ №1:
Используйте два цикла и извлеките информацию перед обработкой файлов данных
for filepath in os.listdir('C:blablablablablaMultiple .mat files'):
if filepath.endswith(".info"):
Fs, gain, base = get_info(filepath)
break
for file in os.listdir('C:blablablablablaMultiple .mat files'):
if file.endswith(".mat"):
file_name=os.path.splitext(file)
...
RawData=sio.loadmat(file)
signalVectors=RawData['val']
...
Я работал над вашим первым редактированием, поэтому я включу это, хотя вопрос был упрощен
# foo.info
Source: record mitdb/100 Start: [00:00:10.000]
val has 2 rows (signals) and 3600 columns (samples/signal)
Duration: 0:10
Sampling frequency: 360 Hz Sampling interval: 0.002777777778 sec
Row Signal Gain Base Units
1 MLII 200 1024 mV
2 V5 200 1024 mV
To convert from raw units to the physical units shown
above, subtract 'base' and divide by 'gain'.
Я бы также написал функцию, которая возвращает нужную вам информацию. Использование функции для извлечения информации делает код в вашем цикле более читаемым и упрощает тестирование извлечения.
Поскольку файл хорошо структурирован, вы, вероятно, могли бы перебирать строки и извлекать информацию, подсчитывая строки и используя str.split
фрагменты и .
Эта функция использует шаблоны регулярных выражений для извлечения информации:
# regex patterns
hz_pattern = r'frequency: (d ) Hz'
mlii_pattern = r'MLIIt(d )t(d )'
def get_info(filepath):
with open(filepath) as f:
info = f.read()
match = re.search(hz_pattern, info)
Fs = match.group(1)
match = re.search(mlii_pattern, info)
gain, base = match.groups()
return map(int, (Fs, gain, base))
Если в каталоге имеется несколько файлов .info и .mat, вы хотите убедиться, что извлекаете правильную информацию для данных. Поскольку файл .info имеет то же имя, что и файл .mat, которому он принадлежит, отсортируйте список каталогов по имени, а затем сгруппируйте по имени — это гарантирует, что вы работаете с двумя файлами, которые связаны друг с другом.
import itertools
def name(filename):
name, extension = filename.split('.')
return name
files = os.listdir('C:blablablablablaMultiple .mat files')
files.sort(key = name)
for fname, _ in itertools.groupby(files, key = name):
fname_info = name '.info'
fname_data = name '.mat'
Fs, gain, base = get_info(fname_info)
# process datafile
Комментарии:
1. Это здорово. Специально для функции, считывающей файл .info. Physionet предлагает скрипт Matlab, который сканирует строки аналогичным образом, как вы делаете здесь . Я хотел сделать это сам, но не смог. Это действительно помогло мне. У меня едва ли есть пара дней, чтобы что-то делать на Python, и эта задача была полезна для устранения сомнений и постановки новых вопросов. большое спасибо!