2011-12-20 24 views
7

Tengo un archivo de muestra lleno de números de punto flotante de la siguiente manera:Determinar la frecuencia de una matriz en Python

-0.02 3.04 3.04 3.02 3.02 3.06 3.04 3.02 3.04 3.02 3.04 3.02 
    3.04 3.02 3.04 3.04 3.04 3.02 3.04 3.02 3.04 3.02 3.04 3.02 
    3.06 3.02 3.04 3.02 3.04 3.02 3.02 3.06 3.04 3.02 3.04 3.02 
    3.04 3.02 3.04 3.04 3.04 3.02 3.04 3.02 3.02 3.06 3.04 3.02 
    3.06 3.02 3.04 -0.02 -0.02 -0.02 -0.02 -0.02 -0.02 -0.04 -0.02 -0.04 

Estos números se colocan en un archivo de texto. Estoy tratando de leer el archivo de texto y determinar la frecuencia de esta señal. Esta información se captura de un osciloscopio digital. Puedo ver la frecuencia en la pantalla de alcance, pero también quiero validarla procesándola en Python. Capturo datos del dispositivo con Python en el lado de la PC.

Aunque puedo hacer algunas cosas de bajo nivel en Python, soy totalmente novato en el procesamiento de texto. Supongo que necesito cargar primero los datos en un archivo en una matriz y luego realizar una FFT o un algoritmo más simple que ceda a un entero en Hz.

En teoría, sé cómo realizar un análisis de Fourier y puedo hacerlo en papel para cualquier señal dada. No tengo idea de dónde comenzar en Python para un determinado conjunto de datos. Ya probé con la documentación de los impertinentes, pero no funcionó tan bien para mí.

Agradecería la orientación de los usuarios con experiencia.

+0

Puede que le resulte útil esta [pregunta relacionada] (http://stackoverflow.com/q/1303307/183066). – jcollado

Respuesta

11

No está claro por su pregunta exactamente lo que representan los valores en el archivo. Pero suponiendo que indican muestras de tensión consecutivos, se puede cargar el archivo en una matriz Numpy usando

import numpy as np 
data = np.array([float(f) for f in file(filename).read().split()]) 

y luego calcular la transformada de Fourier como

import numpy.fft as fft 
spectrum = fft.fft(data) 

A continuación, puede graficar la magnitud de la FFT como

freq = fft.fftfreq(len(spectrum)) 
plot(freq, abs(spectrum)) 

y lo que ves debe coincidir con lo que se muestra en el osciloscopio.

Si desea identificar las frecuencias dominantes en el espectro, tendrá que cortar la matriz en algún umbral, p. algo como esto:

threshold = 0.5 * max(abs(spectrum)) 
mask = abs(spectrum) > threshold 
peaks = freq[mask] 

El contenido de freq (y por tanto también peaks) son las frecuencias en unidades de la frecuencia de muestreo. Por ejemplo, si su osciloscopio muestrea la forma de onda cada microsegundo, los valores en freq están en megahercios. Por lo tanto, si introduce una señal ideal de 1 kHz, puede hacerlo con, por ejemplo,

t = arange(4e6)/1e6 # sampling times in seconds 
data = sin(2 * pi * 1000 * t) 

que se obtiene un pico a 0.001 MHz, y en consecuencia se encuentra que peaks = array([-0.001, 0.001]).

+0

Sí exactamente, los valores almacenados en el archivo son voltajes. Cuando hice lo que sugirió obtuve un siguiente error: ValueError: establecer un elemento de matriz con una secuencia. – y33t

+0

Eso es lo que sucede cuando no todas las líneas del archivo tienen el mismo número de columnas. Prueba la versión editada. –

+0

Con las siguientes correcciones; freq = np.fft.fftfreq (len (spectrum)) He suministrado una señal de 1Khz para validar la operación y el resultado es; 0.00000000e + 00 2.45098039e-05 4.90196078e-05 ..., 7.35294118e-05 -4.90196078e-05 -2.45098039e-05 ¿Qué me falta? – y33t

Cuestiones relacionadas