how to downsample a signal preserving spikes?

  • Last Update :
  • Techknowledgy :

import numpy as np
import matplotlib.pyplot as plt
from collections
import deque

t = np.arange(1000) / 100
y = np.sin(t * 2 * 3.14)
y[150] = 5
y[655] = 5
y[333] = 5
y[250] = 5

def downsample(factor, values):
   buffer_ = deque([], maxlen = factor)
downsampled_values = []
for i, value in enumerate(values):
   buffer_.appendleft(value)
if (i - 1) % factor == 0:
   #Take max value out of buffer
# or you can take higher value
if their difference is too big, otherwise just average
downsampled_values.append(max(buffer_))
return np.array(downsampled_values)

plt.plot(downsample(10, y))
plt.show()

Let's assume data contains your sampling points at constant sampling rate. At the end of this algorithm, the list saved will contain all important [ timestamp, sample_point ] entries of your data:

DIVIDER = 5
THRESHOLD = 1000

saved = [
   [0, data[0]]
]

for i in range(1, len(data)):
   if ((i % DIVIDER == 0) || (abs(data[i] - data[i - 1]) > THRESHOLD)):
      saved.append([i, data[i]])

If you are not too fussy about the aliasing can you just take the maximum of every second (Nth) sample.

def take(N, samples):
   it = iter(samples)
for _ in range(len(samples) / N):
   yield max(it.next() for _ in range(N))

Tensing this:

import random
random.seed(1)

a = [random.gauss(10, 3) for _ in range(100)]

for c in take(5, a):
   print c

Suggestion : 2

I'm analyzing a signal sampled at 200Hz for anycodings_scipy 6-8 seconds, and the important part are the anycodings_scipy spikes, that lasts 1 second at max. Think anycodings_scipy for example to an earthquake... ,(count with the fact that your signal anycodings_scipy will be damaged. You cant downsample anycodings_scipy without losing spikes that are anycodings_scipy represented by one or two points),This is example how to keep the spikes. anycodings_scipy Its just example, as it is now it doesnt anycodings_scipy work for negative values,3) With those spikes you got from 1), anycodings_scipy replace the corresponding downsampled anycodings_scipy values

I have to downsample the signal by a factor anycodings_scipy 2. I tried:

from scipy
import signal

signal.decimate(mysignal, 2, ftype = "fir")
signal.resample_poly(mysignal, 1, 2)

import numpy as np
import matplotlib.pyplot as plt
from collections
import deque

t = np.arange(1000) / 100
y = np.sin(t * 2 * 3.14)
y[150] = 5
y[655] = 5
y[333] = 5
y[250] = 5

def downsample(factor, values):
   buffer_ = deque([], maxlen = factor)
downsampled_values = []
for i, value in enumerate(values):
   buffer_.appendleft(value)
if (i - 1) % factor == 0:
   #Take max value out of buffer
# or you can take higher value
if their difference is too big, otherwise just average
downsampled_values.append(max(buffer_))
return np.array(downsampled_values)

plt.plot(downsample(10, y))
plt.show()

Let's assume data contains your sampling anycodings_scipy points at constant sampling rate. At the anycodings_scipy end of this algorithm, the list saved anycodings_scipy will contain all important [ timestamp, anycodings_scipy sample_point ] entries of your data:

DIVIDER = 5
THRESHOLD = 1000

saved = [
   [0, data[0]]
]

for i in range(1, len(data)):
   if ((i % DIVIDER == 0) || (abs(data[i] - data[i - 1]) > THRESHOLD)):
      saved.append([i, data[i]])

If you are not too fussy about the anycodings_scipy aliasing can you just take the maximum anycodings_scipy of every second (Nth) sample.

def take(N, samples):
   it = iter(samples)
for _ in range(len(samples) / N):
   yield max(it.next() for _ in range(N))

Tensing this:

import random
random.seed(1)

a = [random.gauss(10, 3) for _ in range(100)]

for c in take(5, a):
   print c

Suggestion : 3

Sometimes data exhibit unwanted transients, or spikes. Median filtering is a natural way to eliminate them.,Consider the open-loop voltage across the input of an analog instrument in the presence of 60 Hz power-line noise. The sample rate is 1 kHz.,Corrupt the signal by adding transients with random signs at random points. Reset the random number generator for reproducibility.,MathWorks is the leading developer of mathematical computing software for engineers and scientists.

load openloop60hertz

fs = 1000;
t = (0: numel(openLoopVoltage) - 1) / fs;
rng
default

spikeSignal = zeros(size(openLoopVoltage));
spks = 10: 100: 1990;
spikeSignal(spks + round(2 * randn(size(spks)))) = sign(randn(size(spks)));

noisyLoopVoltage = openLoopVoltage + spikeSignal;

plot(t, noisyLoopVoltage)

xlabel('Time (s)')
ylabel('Voltage (V)')
title('Open-Loop Voltage with Added Spikes')
yax = ylim;
medfiltLoopVoltage = medfilt1(noisyLoopVoltage, 3);

plot(t, medfiltLoopVoltage)

xlabel('Time (s)')
ylabel('Voltage (V)')
title('Open-Loop Voltage After Median Filtering')
ylim(yax)
grid