【问题标题】:Iterate the code in a shortest way for the whole dataset以最短的方式迭代整个数据集的代码
【发布时间】:2019-08-27 21:57:08
【问题描述】:

我的 df 很大:

df.shape() = (106, 3364)

我想用这个Frechet Distance between 2 curves 计算所谓的frechet 距离。而且效果很好。示例:

x = df['1']
x1 = df['1.1']
p = np.array([x, x1])

y = df['2']
y1 = df['2.1']
q = np.array([y, y1])

P_final = list(zip(p[0], p[1]))
Q_final = list(zip(q[0], q[1]))

from frechetdist import frdist

frdist(P_final,Q_final)

但我不能像这样逐行做:

`1 and 1.1` to `1 and 1.1` which is equal to 0
`1 and 1.1` to `2 and 2.1` which is equal to some number
...
`1 and 1.1` to `1682 and 1682.1` which is equal to some number

我想创建一些东西(第一个想法是 for 循环,但也许你有更好的解决方案)来计算以下 frdist(P_final,Q_final)

  • 第一行到所有行(包括自身)
  • 第二行到所有行(包括自身)

最后,我应该得到一个 ma​​trix 大小 (106,106)0 在对角线上(因为它之间的距离是 0

矩阵 =

  0 1 2 3 4 5 ... 105
0 0
1   0
2     0
3       0  
4         0
5           0
...           0
105              0

不包括我的试用代码,因为它让每个人都感到困惑!

编辑: 样本数据:

    1           1.1     2           2.1     3           3.1     4           4.1     5           5.1
0   43.1024     6.7498  45.1027     5.7500  45.1072     3.7568  45.1076     8.7563  42.1076     8.7563
1   46.0595     1.6829  45.0595     9.6829  45.0564     4.6820  45.0533     8.6796  42.0501     3.6775
2   25.0695     5.5454  44.9727     8.6660  41.9726     2.6666  84.9566     3.8484  44.9566     1.8484
3   35.0281     7.7525  45.0322     3.7465  14.0369     3.7463  62.0386     7.7549  65.0422     7.7599
4   35.0292     7.5616  45.0292     4.5616  23.0292     3.5616  45.0292     7.5616  25.0293     7.5613

【问题讨论】:

  • 好吧..我建议您提供一些示例数据。
  • 距离对称吗?意味着 F(a, b) = F(b, a)?
  • 类似于矩阵乘法(X.T dot X)
  • @RicHard Exatly。矩阵是对称的
  • 好的,如果您发布您的 df=... 代码,猜猜人们可以帮助您。

标签: python pandas numpy for-loop distance


【解决方案1】:

我只是使用了你的格式的样本数据(我希望)

import pandas as pd
from frechetdist import frdist
import numpy as np

# create sample data
df = pd.DataFrame([[1,2,3,4,5,6], [3,4,5,6,8,9], [2,3,4,5,2,2], [3,4,5,6,7,3]], columns=['1','1.1','2', '2.1', '3', '3.1'])

# this matrix will hold the result
res = np.ndarray(shape=(df.shape[1] // 2, df.shape[1] // 2), dtype=np.float32)

for row in range(res.shape[0]):
    for col in range(row, res.shape[1]):

        # extract the two functions
        P = [*zip([df.loc[:, f'{row+1}'], df.loc[:, f'{row+1}.1']])]
        Q = [*zip([df.loc[:, f'{col+1}'], df.loc[:, f'{col+1}.1']])]

        # calculate distance
        dist = frdist(P, Q)

        # put result back (its symmetric)
        res[row, col] = dist
        res[col, row] = dist

# output
print(res)

输出:

[[0.        4.        7.5498343]
 [4.        0.        5.5677643]
 [7.5498343 5.5677643 0.       ]]

希望有帮助

编辑:一些一般提示:

  • 如果速度很重要:检查 frdist 是否也处理一个 numpy 形状数组 (n_values, 2) 比你可以节省相当昂贵的压缩和解压操作 并直接使用数组或直接以库需要的格式构建数据

  • 通常,使用更好的列命名(3 和 3.1 不太明显)。为什么你不称它们为 x3、y3 或 x3 和 f_x3

  • 我实际上会将数据放入两个不同的矩阵中。如果你看 代码我不得不做一些不那么明显的事情,比如迭代形状 由于给定的表格布局,除以二并从字符串操作中构建索引

【讨论】:

  • 这完全不清楚,因为距离测量需要两个 (xs, ys) 对。那么什么是 P_x 和 P_y 以及 Q_x 和 Q_y。相同的逻辑是否假设相邻行包含之前行的 y 值?如果是这样,它对代码的更改是微不足道的。
  • 如果假设我们只执行df = df.T 并使用行索引切换列,那么行方式的解决方案对于列方式来说无论如何都是相同的。但是由于 OP 没有澄清,所以讨论这个问题没有任何意义。
猜你喜欢
  • 2016-08-29
  • 2021-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
相关资源
最近更新 更多