python中不同长度的点的平均多个向量

时间:2013-04-26 09:49:58

标签: python interpolation

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

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将点(x,y)添加到正确位置的Y vec,如使用平均值之前和之后的点或中位数?

修改: 我能想到的最简单的例子是使用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)时间序列中抽出时间。因此,问题就变成了引入新价值的地方,以及我选择“网站”的标准。对于插入值,我推断值的方式现在似乎不那么重要......

1 个答案:

答案 0 :(得分: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