每个点都有时间序列的点之间的相关性下降

问题描述

我正在研究如何快速实现计算点之间的相关性(在X、Y、Z中),并在给定搜索方向的情况下测量相关性何时降至特定阈值以下。我在Calculating correlation between points where each points has a timeseries之前提出了一个相关问题,但我认为我需要重新表述这个问题以使其更清楚。

我有平面中点速度的时间历史,例如XZ平面,我想量化用于模拟(CFD模拟)的分辨率。为此,我想计算点之间的速度时程之间的皮尔逊相关系数,我想测量给定轴(例如沿X轴)的点的数量,直到相关性降到某个阈值以下(例如0.8)。

我现在有一个DataFrame中的所有数据,头部看起来像:

    Velocity      X  Y      Z   Time  
0 -12.125850  2.036  0  1.172  10.42
1 -12.516033  2.036  0  1.164  10.42
2 -11.816067  2.028  0  1.172  10.42
3 -10.722124  2.020  0  1.180  10.42
4 -10.628474  2.012  0  1.188  10.42
...

我希望在某些方向上输出这个点数,仅作为一个示例

    X    Y      Z  CorrDropNrPointsX       CorrDropNrPointsZ       
0 2.036  0  1.172  5                       12
1 2.036  0  1.164  7                       21
2 2.028  0  1.172  4                       18 
3 2.020  0  1.180  12                      19
4 2.012  0  1.188  5                       22
...

在我当前的实现中,我经常使用循环,例如.iterrow(),这永远需要花费很长时间,因为我的DataFrame中可以很容易地有30万行,所以我需要加快速度。

我现在使用直线来检测某一方向沿轴的点数

df_lines = df[[loop_axis]].drop_duplicates()

但平面中的点不一定完全对齐(可能存在1-e4 m量级的微小数值差异,这可能会导致这种方法的误差,有时点可能会结束,因为平面直接穿过几何图形,如果发生这种情况,则应该相互独立地查看一组点-例如,阈值距离D_L~1-e2 m。

我得到的前一个解决方案非常强大,它使用

计算所有点之间的相关性
df["cc"] = df.groupby(["X", "Y", "Z"]).cumcount()
df.set_index(["cc","X", "Y", "Z"], inplace=True)
df.unstack(level=[1,2,3])["Velocity"].corr()

然而,我意识到在加载时,点不一定以正确的方式排序,因此需要这样做,对于最终的数据帧,我仍然循环通过行或列来测量相关性何时降至某个阈值以下。这种方法的另一个问题是,它将所有点之间的相关性计算为两倍,因此它将计算corr(P1,P2)和corr(P2,P1),还将计算所有点的相关性。我不需要计算对角点之间的相关性,而只需要计算定义方向上的相关性。

所有点具有相同的时间点数量,因此以相同的频率和相同的开始和结束时间进行采样。


解决方案

我想我多少明白您想要什么。

corr_df = df.unstack(level=[1,2,3])["Velocity"].corr()

可以对关联矩阵进行排序。

corr_df.sort_index(level=0, inplace=True)

X为0,Y为1,Z为2。

您说您想要相关性大于.80的点数。

corr_df_x = corr_df.sort_index(level=0)
corr_df_y = corr_df.sort_index(level=1)
corr_df_z = corr_df.sort_index(level=2)
然后创建计算连续&>0.8个数的系列。这是与列中的第一点的比较:

x_df = (df.iloc[:,0].sort_index(level=0)  
       .groupby(df.iloc[:,0].gt(0.8).sort_index(level=0)
       .ne(df.iloc[:,0].gt(0.8).sort_index(level=0).shift())
       .cumsum())
       .transform(lambda x: np.arange(1,len(x)+1)[::-1]))
x_df = x_df.where(df.sort_index(level=0).iloc[:,0].gt(0.8),0)
因此,x_df将按X排序,对于每个点,它将显示在x方向上从该点开始大于0.8的点数,包括当前点。但我不能百分之百确定你想要什么。

相关文章