TL; DR:无论如何,我可以摆脱我的第二个for
- 循环吗?
我在2D网格上有一系列时间点。为了消除它们位置的快速波动,我在一个帧窗口上平均坐标。现在在我的情况下,这些点可能比平时覆盖更大的距离。如果特定点的帧数超过cut_off
值,我不想包含特定点的帧。
在第一个for
循环中,我遍历所有帧并定义移动窗口。然后,我计算当前帧与移动窗口中每个帧之间的距离。在我仅抓取所有框架中的那些位置后,x
和y
组件的行进距离都不超过cut_off
。现在我想计算移动窗口所有这些选定帧中每个点的平均位置(注意:所选帧的数量 小于{{1} })。这导致我进入第二个n_window
循环。在这里,我迭代所有点并实际抓住帧中的位置,其中当前点不的行程比for
更远。从这些选定的帧中,我计算坐标的平均值,并将其用作当前帧的新值。
这最后一个cut_off
循环减缓了整个处理过程。我无法想出一个更好的方法来完成这个计算。有什么建议吗?
提出意见澄清。
for
答案 0 :(得分:0)
如果您可以分别计算x和y中的截止距离,则可以使用scipy.ndimage.generic_filter
。
import numpy as np
from scipy.ndimage import generic_filter
def _mean(x, cutoff):
is_too_different = np.abs(x - x[len(x) / 2]) > cutoff
return np.mean(x[~is_too_different])
def _smooth(x, window_length=5, cutoff=1.):
return generic_filter(x, _mean, size=window_length, mode='nearest', extra_keywords=dict(cutoff=cutoff))
def smooth(arr, window_length=5, cutoff=1., axis=-1):
return np.apply_along_axis(_smooth, axis, arr, window_length=window_length, cutoff=cutoff)
# --------------------------------------------------------------------------------
def _simulate_movement_2d(T, fraction_is_jump=0.01):
# generate random velocities with a few "jumps"
velocity = np.random.randn(T, 2)
is_jump = np.random.rand(T) < fraction_is_jump
jump = 10 * np.random.randn(T, 2)
jump[~is_jump] = 0.
# pre-allocate position and momentum arrays
position = np.zeros((T,2))
momentum = np.zeros((T,2))
# initialise the first position
position[0] = np.random.randn(2)
# update position using velocity vector:
# smooth movement by not applying the velocity directly
# but rather by keeping track of the momentum
for ii in range(2,T):
momentum[ii] = 0.9 * momentum[ii-1] + 0.1 * velocity[ii-1]
position[ii] = position[ii-1] + momentum[ii] + jump[ii]
# add some measurement noise
noise = np.random.randn(T,2)
position += noise
return position
def demo(nframes=1000, npoints=3):
# create data
positions = np.array([_simulate_movement_2d(nframes) for ii in range(npoints)])
# format to (nframes, npoints, 2)
position = positions.transpose([1, 0, 2])
# smooth
smoothed = smooth(positions, window_length=11, cutoff=5., axis=1)
# plot
x, y = positions.T
xs, ys = smoothed.T
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1)
ax.plot(x, y, 'o')
ax.plot(xs, ys, 'k-', alpha=0.3, lw=2)
plt.show()
demo()