0

我有一个不同试验的轨迹列表,它们本身就是一个点列表......

trajectories = [[(x,y),(x,y), ...], [(x,y), ...], ...]

分数的数量因试验而异。

最终目标是在试验中绘制平均轨迹 +/- SEM(平均值的标准误差)。

据我所知,我应该得到最长的轨迹,并为每个剩余的轨迹添加“分辨率”到其他向量,使它们的长度相同,所以是这样的:

#find the maximum length
max_len = len(trajectories[0])
longest = []
for t in trajectories:
    if len(t) > max_len:
        max_len = len(t)
        longest = t
# now transform the other vectors I assume using the longest vector or the length of this vector 
newTrajectories = []
for i,t in enumerate(trajectories):
    newTrajectories[i] = resample(t, longest or max_len, or something similar!!)

是否有一个函数给出 len X 的元组 (x,y) 和另一个 len Y 的 vec,其中 X>Y 在正确的位置向 Y vec 添加点 (x,y),例如使用前后的平均值点还是中位数?

编辑:我能想到的最简单的例子是使用 2 个轨迹向量:

vec_one = [(2,4),(3,5),(1,6)]
vec_two = [(2,4), (1,6)]

它们都从 x=2, y=4 开始,最终以 x=1, y=6 vec_o​​ne 结束,但是更长(花费了更多时间)。我认为为了能够对轨迹进行平均,vec_two 需要更长,所以我需要以某种方式推断缺少的 x,y 位置的值。

我一直在研究 scypi.interpolate 模块的 splprep、splrep 和 splev,但恐怕我还不太了解它们。

Edit2:实际上,我试图从 (x,y) 时间序列中抽象出时间。所以问题变成了在哪里引入新值以及我选择一个“站点”来插入值的标准,我推断值的方式现在似乎不那么重要了......

4

1 回答 1

1

不幸的是,没有接受者,这是我认为可行的解决方案。

我不得不改变数据的格式来解决这个问题。因此,不要有一个具有可变数量 (x, y) 点的试验列表:[[(x, y), (x, y), ...], [(x, y), (...) , ...]]

我现在有 3 个 numpy.arrays:

sx = 数组([ 23, 34, 42, ..., 56, 56, 63])

sy = 数组([ 78, 94, 20, ..., 44, 38, 34])

st = 数组([1, 1, 1, ..., 293, 293, 293])

所有向量的长度相同,因为它们本质上是表的一部分,其中sx是包含所有 x 位置的列,sy是所有 y 位置,st是试验编号(或 x 和 y 位置的列表 ID) . st基本上是一堆重复的数字 [1,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,...]

(我实际上是使用 HDF5/pytables 来存储我的数据,并直接从包含跟踪数据的表中读取)

此解决方案使用 interp1d

from scipy.interpolate import interp1d

当然还有 numpy

import numpy as np

我承认这是一个被黑的解决方案,速度不是很快,但它确实有效:) 另一方面,重新阅读我自己的问题让我认为这不是对我的问题的一个非常清楚的阐述......对此感到抱歉。无论如何,这是解决方案。

下面的 func 接收我上面描述的 3 个 vecs,一个trialList是要折叠的试验列表,而kind是你想要做的折叠类型,现在可以是均值或中值。它将返回折叠的轨迹,即 trialList 的平均值或中值的 x 和 y 位置

def collapseTrajectories(sx, sy, st, trialList, kind='median'):
    # find the longest trial to use as template
    l = 0
    tr = []
    for t in trialList:
        if len(st[st==t]) > l:
            l = len(st[st==t])
            tr = t

    # Make all vectors the same length by interpolating the values
    xnew = np.linspace(0, 640, l)
    ynew = np.linspace(0, 480, l)
    sx_new = []
    sy_new = []

    for t in trialList:
        if len(st[st==t]) > 3:
            X = sx[st==t]
            Y = sy[st==t]
            x = np.linspace(0,640, len(X))
            y = np.linspace(0,480,len(Y))
            fx = interp1d(x, X, kind='cubic')
            fy = interp1d(y, Y, kind='cubic')
            sx_new.append(fx(xnew))
            sy_new.append(fy(ynew))

    # Collapse using the appropriate kind
    if kind == 'median':
        out_x = np.median(sx_new, axis=0)
        out_y = np.median(sy_new, axis=0)
    elif kind=='mean':
        out_x = np.mean(sx_new, axis=0)
        out_y = np.mean(sy_new, axis=0)

    return out_x, out_y
于 2013-05-15T15:47:09.220 回答