2015-01-01 3 views
1

Я пытаюсь сгладить этот набор данных и создать единую репрезентативную кривую с ошибками. Метод получения точек данных был дискретизирован с довольно грубым шагом. У меня мало опыта программирования, но я стараюсь учиться. Я читал, что фильтр Гаусса может быть хорошим вариантом. Любая помощь будет оценена по достоинству. Optical dilatometer data for shrinkage of a ceramic pelletСглаживание дискретного набора данных

Вот набор примеров данных:

Time (min) Non-Normalized Shrinkage Normalized Shrinkage 
200 93 1.021978022 
202 92 1.010989011 
204 92 1.010989011 
206 92 1.010989011 
208 92 1.010989011 
210 92 1.010989011 
212 91 1 
214 90 0.989010989 
216 90 0.989010989 
218 90 0.989010989 
220 88 0.967032967 
222 88 0.967032967 
224 87 0.956043956 
226 86 0.945054945 
228 86 0.945054945 
230 86 0.945054945 
232 86 0.945054945 
234 86 0.945054945 
236 85 0.934065934 
238 84 0.923076923 
240 83 0.912087912 
242 83 0.912087912 
244 83 0.912087912 
246 82 0.901098901 
248 83 0.912087912 
250 82 0.901098901 
252 81 0.89010989 
254 81 0.89010989 
256 82 0.901098901 
258 82 0.901098901 
260 79 0.868131868 
262 80 0.879120879 
264 80 0.879120879 

Я нашел этот фрагмент кода на сайте где-то, но я не знаю, как реализовать его или это даже то, что я ищу.

def smoothListGaussian(list,degree=5): 

window=degree*2-1 

weight=numpy.array([1.0]*window) 

weightGauss=[] 

for i in range(window): 

    i=i-degree+1 

    frac=i/float(window) 

    gauss=1/(numpy.exp((4*(frac))**2)) 

    weightGauss.append(gauss) 

weight=numpy.array(weightGauss)*weight 

smoothed=[0.0]*(len(list)-window) 

for i in range(len(smoothed)): 

    smoothed[i]=sum(numpy.array(list[i:i+window])*weight)/sum(weight) 

return smoothed 
+0

Можете ли вы предоставить код, который у вас есть до сих пор? И пример набора данных? – Ffisegydd

+0

У меня до сих пор нет кода. Я нашел этот кусок, который я вставил выше, но я не знаю, как его реализовать. Извините, что я такой noob. – SeattleFreezer

ответ

4

Как правило, для этого вы использовали бы библиотеку, а не ее реализацию самостоятельно.

Я собираюсь использовать scipy.ndimage для этого вместо scipy.signal. Если у вас есть класс обработки сигналов, вы, вероятно, найдете подход scipy.signal более интуитивным, но если это не так, это может показаться запутанным. scipy.ndimage обеспечивает прямолинейный однофункциональный вызов gaussian_filter, в отличие от необходимости понимать еще несколько соглашений обработки сигналов.

Вот краткий пример, используя данные, опубликованные в вашем вопросе. Это предполагает, что ваши данные регулярно отбираются (это: каждые 2 единицы во времени).

import numpy as np 
import matplotlib.pyplot as plt 
import scipy.ndimage 

time, _, shrinkage = np.loadtxt('discrete_data.txt', skiprows=1).T 

fig, ax = plt.subplots() 
ax.plot(time, shrinkage, 'ro') 
ax.plot(time, scipy.ndimage.gaussian_filter(shrinkage, 3)) 
plt.show() 

enter image description here

Большинство это довольно прямо вперед, но вы можете заметить «магическое» значение 3, что я указал в scipy.ndimage.gaussian_filter(shrinkage, 3). Это параметр sigma гауссовой функции в образцах. Поскольку ваши данные отбираются каждые 2 единицы во времени, это sigma из 6 единиц.

Параметр sigma в точности аналогичен стандартным отклонениям в нормальном распределении «колоколообразная кривая». Чем больше вы это сделаете, тем шире будет функция gaussian, а более гладкой будет ваша кривая. По результатам проб и ошибок значение 3 кажется правильным для этого конкретного набора данных, но вы должны поэкспериментировать и посмотреть, что, по вашему мнению, выглядит лучше всего.

Еще одно заключительное примечание. Существует множество различных способов решения этой проблемы. Гауссовский фильтр - разумное решение, но есть много и многие другие. Если точный результат очень важен, вам, вероятно, следует сравнить несколько методов и посмотреть, какие из них лучше всего подходят для вашего конкретного набора данных.


В своем комментарии вы задали вопрос о сохранении сглаженных данных в файл, а не в его построении. Вот краткий пример того, как вы можете это сделать:

import numpy as np 
import scipy.ndimage 

time, _, shrinkage = np.loadtxt('discrete_data.txt', skiprows=1).T 
smoothed = scipy.ndimage.gaussian_filter(shrinkage, 3) 

np.savetxt('smoothed_data.txt', np.c_[time, smoothed]) 
+0

Большое спасибо. Я попытаюсь реализовать это. Точное решение не имеет значения, это больше для целей презентации. У меня есть несколько кривых из разных образцов, и я собираюсь построить их один поверх другого. – SeattleFreezer

+0

К сожалению, у меня возникли трудности с библиотекой matplotlib.pyplot. 'ImportError: Нет модуля с именем matplotlib.pyplot' Я попытался изменить преамбулу, чтобы указать, где установлен matplotlib, но это, похоже, не работает. На самом деле было бы более выгодно просто получить сюжет гауссовых данных, которые я могу потом заговорить. Как мне это сделать? – SeattleFreezer

+0

@SeattleFreezer - Как вы установили matplotlib? Возможно ли, что у вас установлено более одного исполняемого файла python, и вы установили matplotlib для одного, но не для другого? –

Смежные вопросы