【发布时间】:2018-02-03 08:22:51
【问题描述】:
TL;DR:有没有办法摆脱我的第二个for-loop?
我在二维网格上有一个时间序列的点。为了摆脱它们位置的快速波动,我在一个帧窗口上平均坐标。现在就我而言,这些点可能会比平时覆盖更大的距离。我不想包含特定点的帧,如果它比cut_off 值更远。
在第一个for-loop 中,我遍历所有帧并定义移动窗口。然后我计算当前帧和移动窗口中每个帧之间的距离。在我只从所有帧中抓取这些位置之后,x 和y 组件的移动距离都没有超过cut_off。现在我想从移动窗口的所有这些选定帧中计算每个点的平均位置(注意:选定帧的数量可以小于n_window) .这导致我进入第二个for-loop。在这里,我遍历所有点并实际从帧中获取位置,其中当前点没有比cut_off 移动得更远。从这些选定的帧中,我计算坐标的平均值并将其用作当前帧的新值。
最后一个for-loop 减慢了整个处理速度。我想不出更好的方法来完成这个计算。有什么建议吗?
MWE
放入 cmets 以便澄清。
import numpy as np
# Generate a timeseries with 1000 frames, each
# containing 50 individual points defined by their
# x and y coordinates
n_frames = 1000
n_points = 50
n_coordinates = 2
timeseries = np.random.randint(-100, 100, [n_frames, n_points, n_coordinates])
# Set window size to 20 frames
n_window = 20
# Distance cut off
cut_off = 60
# Set up empty array to hold results
avg_data_store = np.zeros([n_frames, timeseries.shape[1], 2])
# Iterate over all frames
for frame in np.arange(0, n_frames):
# Set the frame according to the window size that we're looking at
t_before = int(frame - (n_window / 2))
t_after = int(frame + (n_window / 2))
# If we're trying to access frames below 0, set the lowest one to 0
if t_before < 0:
t_before = 0
# Trying to access frames that are not in the trajectory, set to last frame
if t_after > n_frames - 1:
t_after = n_frames - 1
# Grab x and y coordinates for all points in the corresponding window
pos_before = timeseries[t_before:frame]
pos_after = timeseries[frame + 1:t_after + 1]
pos_now = timeseries[frame]
# Calculate the distance between the current frame and the windows before/after
d_before = np.abs(pos_before - pos_now)
d_after = np.abs(pos_after - pos_now)
# Grab indices of frames+points, that are below the cut off
arg_before = np.argwhere(np.all(d_before < cut_off, axis=2))
arg_after = np.argwhere(np.all(d_after < cut_off, axis=2))
# Iterate over all points
for i in range(0, timeseries.shape[1]):
# Create temp array
temp_stack = pos_now[i]
# Grab all frames in which the current point did _not_
# travel farther than `cut_off`
all_before = arg_before[arg_before[:, 1] == i][:, 0]
all_after = arg_after[arg_after[:, 1] == i][:, 0]
# Grab the corresponding positions for this points in these frames
all_pos_before = pos_before[all_before, i]
all_pos_after = pos_after[all_after, i]
# If we have any frames for that point before / after
# stack them into the temp array
if all_pos_before.size > 0:
temp_stack = np.vstack([all_pos_before, temp_stack])
if all_pos_after.size > 0:
temp_stack = np.vstack([temp_stack, all_pos_after])
# Calculate the moving window average for the selection of frames
avg_data_store[frame, i] = temp_stack.mean(axis=0)
【问题讨论】:
-
这听起来有点像你在尝试重新发明卡尔曼滤波器。
-
只是为了澄清:问题是 (a) 存在您想要摆脱的测量伪影/异常值,或者 (b) 您的粒子运动中存在真正的跳跃不想通过移动窗口平均值求平均值?
-
@Paul 这是第二个问题。基本上我在一个盒子里模拟粒子,并且通过周期性边界条件,它们能够跳过盒子障碍。如果粒子在给定的帧窗口中连续跳过屏障,则其平均位置在框的中间。