Python 平滑
Smoothing in Python
我经常为我的数据使用时间平均视图,这样我绘制它时噪音会更少。例如,如果我的数据每 1 分钟取一次,那么我有两个数组,ts
和 ys
。然后我创建了 fs
,它是 ys
中 60 个最近点的局部平均值。我通过简单地计算 60 个最近点的平均值来自己进行此卷积,因此我不使用 numpy
或其他任何模块。
我有新数据,其中 ts
有点稀疏。也就是说,有时我会错过一些数据点,所以我不能简单地取最近 60 个点的平均值。如果我的自变量 ts
以分钟为单位,我如何计算我的因变量 ys
的每小时平均值以创建每小时平均值函数 fs
,在 [=20] =]?
If my independent variable, ts, is in minutes, how do I calculate an hourly average of my dependent variable, ys, to create an hourly average function, fs, in python?
这是一个复杂的问题,可能的答案会有很大差异,具体取决于 "hourly average"。
处理 irregularly-spaced 数据的一种方法是对其重新采样。重采样可以通过插值完成,然后生成的重采样数据可用于您喜欢的任何过滤方法。
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter
%matplotlib inline
def y(t):
# a function to simulate data
return np.sin(t/20.) + 0.05*np.random.randn(len(t))
four_hours = np.arange(240)
random_time_points = np.sort(np.random.choice(four_hours, size=30, replace=False))
simulated_data = y(random_time_points)
resampled_data = np.interp(four_hours, random_time_points, simulated_data)
# here I smooth with a Savitzky-Golay filter,
# but you could use a moving avg or anything else
# the window-length=61 means smooth over a 1-hour (60 minute) window
smoothed_data = savgol_filter(resampled_data, window_length=61, polyorder=0)
# plot some results
plt.plot(random_time_points, simulated_data, '.k',
four_hours, smoothed_data, '--b',
four_hours, y(four_hours), '-g')
# save plot
plt.savefig('SO35038933.png')
该图显示原始 "sparse" 数据(黑点)、原始 "true" 数据(绿色曲线)和平滑数据(蓝色虚线)。
如果我对您的理解正确,我认为这样的方法可能有效。
import threading
hours_worth_of_data = []
def timer():
threading.Timer(3600, timer).start() #3600 seconds in an hour
smooth = sum(hours_worth_of_data) / len(hours_worth_of_data)
# do something with smooth here
del hours_worth_of_data[:] #Start over with fresh data for next hour
timer()
无论何时获取数据,也将数据加载到 "hours_worth_of_data." 每小时它会对数据进行平均,然后删除列表中的数据。
我最终创建了一个数组来表示我感兴趣的时间单位的数据,然后对该数组进行统计。例如,将 'minute' 时间创建为 'hour' 时间,并使用该小时内 ys
的平均值:
for i in range(len(ts0)):
tM = ts0[i] # time in minutes
tH = tM/60.0 # time in hours
tHs[i] = int(tH) # now this is the data within hour tH
tHs0 = tHs[:] # keep a record of the original hourly times, there are repeats here
tHs = list(set(tHs0)) # now we have a list of the hours with no repeats
for i in range(len(ts0)):
y0 = ys0[i]
t0 = ts0[i]
tH = int(t0/60.0)
ys[tHs.index(tH)] += R0
Cs[tHs.index(tH)] += 1 # keep a record of how many times this was seen
for i in range(len(ys)):
ys[i] = ys[i]/Cs[i]
我经常为我的数据使用时间平均视图,这样我绘制它时噪音会更少。例如,如果我的数据每 1 分钟取一次,那么我有两个数组,ts
和 ys
。然后我创建了 fs
,它是 ys
中 60 个最近点的局部平均值。我通过简单地计算 60 个最近点的平均值来自己进行此卷积,因此我不使用 numpy
或其他任何模块。
我有新数据,其中 ts
有点稀疏。也就是说,有时我会错过一些数据点,所以我不能简单地取最近 60 个点的平均值。如果我的自变量 ts
以分钟为单位,我如何计算我的因变量 ys
的每小时平均值以创建每小时平均值函数 fs
,在 [=20] =]?
If my independent variable, ts, is in minutes, how do I calculate an hourly average of my dependent variable, ys, to create an hourly average function, fs, in python?
这是一个复杂的问题,可能的答案会有很大差异,具体取决于 "hourly average"。
处理 irregularly-spaced 数据的一种方法是对其重新采样。重采样可以通过插值完成,然后生成的重采样数据可用于您喜欢的任何过滤方法。
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter
%matplotlib inline
def y(t):
# a function to simulate data
return np.sin(t/20.) + 0.05*np.random.randn(len(t))
four_hours = np.arange(240)
random_time_points = np.sort(np.random.choice(four_hours, size=30, replace=False))
simulated_data = y(random_time_points)
resampled_data = np.interp(four_hours, random_time_points, simulated_data)
# here I smooth with a Savitzky-Golay filter,
# but you could use a moving avg or anything else
# the window-length=61 means smooth over a 1-hour (60 minute) window
smoothed_data = savgol_filter(resampled_data, window_length=61, polyorder=0)
# plot some results
plt.plot(random_time_points, simulated_data, '.k',
four_hours, smoothed_data, '--b',
four_hours, y(four_hours), '-g')
# save plot
plt.savefig('SO35038933.png')
该图显示原始 "sparse" 数据(黑点)、原始 "true" 数据(绿色曲线)和平滑数据(蓝色虚线)。
如果我对您的理解正确,我认为这样的方法可能有效。
import threading
hours_worth_of_data = []
def timer():
threading.Timer(3600, timer).start() #3600 seconds in an hour
smooth = sum(hours_worth_of_data) / len(hours_worth_of_data)
# do something with smooth here
del hours_worth_of_data[:] #Start over with fresh data for next hour
timer()
无论何时获取数据,也将数据加载到 "hours_worth_of_data." 每小时它会对数据进行平均,然后删除列表中的数据。
我最终创建了一个数组来表示我感兴趣的时间单位的数据,然后对该数组进行统计。例如,将 'minute' 时间创建为 'hour' 时间,并使用该小时内 ys
的平均值:
for i in range(len(ts0)):
tM = ts0[i] # time in minutes
tH = tM/60.0 # time in hours
tHs[i] = int(tH) # now this is the data within hour tH
tHs0 = tHs[:] # keep a record of the original hourly times, there are repeats here
tHs = list(set(tHs0)) # now we have a list of the hours with no repeats
for i in range(len(ts0)):
y0 = ys0[i]
t0 = ts0[i]
tH = int(t0/60.0)
ys[tHs.index(tH)] += R0
Cs[tHs.index(tH)] += 1 # keep a record of how many times this was seen
for i in range(len(ys)):
ys[i] = ys[i]/Cs[i]