应用于整个数据集的函数
Function applied to the whole dataset
手动定义p和q:
p = [[45.1024,7.7498],[45.1027,7.7513],[45.1072,7.7568],[45.1076,7.7563]]
q = [[45.0595,7.6829],[45.0595,7.6829],[45.0564,7.6820],[45.0533,7.6796],[45.0501,7.6775]]
- 第 1 步(精细)
部分代码还不错
def _c(ca, i, j, p, q):
if ca[i, j] > -1:
return ca[i, j]
elif i == 0 and j == 0:
ca[i, j] = np.linalg.norm(p[i]-q[j])
elif i > 0 and j == 0:
ca[i, j] = max(_c(ca, i-1, 0, p, q), np.linalg.norm(p[i]-q[j]))
elif i == 0 and j > 0:
ca[i, j] = max(_c(ca, 0, j-1, p, q), np.linalg.norm(p[i]-q[j]))
elif i > 0 and j > 0:
ca[i, j] = max(
min(
_c(ca, i-1, j, p, q),
_c(ca, i-1, j-1, p, q),
_c(ca, i, j-1, p, q)
),
np.linalg.norm(p[i]-q[j])
)
else:
ca[i, j] = float('inf')
return ca[i, j]
- 第 2 步(问题出在这里)是
def frdist(p, q):
# Remove nan values from p
p = np.array([i for i in p if np.any(np.isfinite(i))], np.float64) # ESSENTIAL PART TO REMOVE NaN
q = np.array([i for i in q if np.any(np.isfinite(i))], np.float64) # ESSENTIAL PART TO REMOVE NaN
len_p = len(p)
len_q = len(q)
if len_p == 0 or len_q == 0:
raise ValueError('Input curves are empty.')
# p and q no longer have to be the same length
if len(p[0]) != len(q[0]):
raise ValueError('Input curves do not have the same dimensions.')
ca = (np.ones((len_p, len_q), dtype=np.float64) * -1)
dist = _c(ca, len_p-1, len_q-1, p, q)
return(dist)
frdist(p, q)
0.09754839824415232
问题:
在第 2 步 中要做什么以将代码应用到给定的(再次是示例数据集。真实数据集非常大)数据集 df:
1 1.1 2 2.1 3 3.1 4 4.1 5 5.1
0 43.1024 6.7498 NaN NaN NaN NaN NaN NaN NaN NaN
1 46.0595 1.6829 25.0695 3.7463 NaN NaN NaN NaN NaN NaN
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 NaN NaN NaN NaN
4 35.0292 7.5616 45.0292 4.5616 23.0292 3.5616 45.0292 6.7463 NaN
通过取 p 第一行和 q 第二行。然后计算距离frdist(p, q)
。然后 p 又是第一行,但 q 现在是第三行。然后是 1 和 3.
最后我应该得到对角线为 0 的行 (rows, rows) 大小的矩阵。因为它们之间的距离是0:
0 1 2 3 4 5 ... 105
0 0
1 0
2 0
3 0
4 0
5 0
... 0
105 0
由于您的工作代码需要列表列表作为参数,因此您需要将数据框的每一行转换为列表列表,例如示例中的 p
和 q
。假设 df
是您的数据框,您可以按以下方式执行此操作:
def pairwise(it):
a = iter(it)
return zip(a, a)
ddf = df.apply(lambda x : [pair for pair in pairwise(x)], axis=1)
我从 this answer 中获取了 pairwise
函数。
ddf
是一个只有一列的数据框,每个元素都是一个列表,如 p
或 q
.
然后您需要使用行索引的组合。看看 itertools module. Depending on your needs, you can use one from product, permutations or combinations.
如果你想做每一个组合,你可以使用:
from itertools import product
idxpairs = product(ddf.index, repeat=2)
idxpairs
包含数据框中所有可能的索引对。你可以遍历它们。
您可以像这样构建最终矩阵:
fmatrix = pd.DataFrame(index=ddf.index, columns=ddf.index)
for pp in idxpairs:
fmatrix.loc[pp[0], pp[1]] = frdist(ddf.iloc[pp[0]], ddf.iloc[pp[1]])
现在这将计算暴力计算每个元素。如果你有一个大数据框并且你事先知道你的最终矩阵将具有给定的属性,比如对角线为 0 并且它是对称的(我猜 frdist(p, q) == frdist(q, p)
)你可以通过使用例如 [=23 来节省一些时间=] 而不是 product
不执行两次相同的计算:
from itertools import combinations
idxpairs = combinations(ddf.index, 2)
fmatrix = pd.DataFrame(index=ddf.index, columns=ddf.index)
for pp in idxpairs:
res = frdist(ddf.iloc[pp[0]], ddf.iloc[pp[1]])
fmatrix.loc[pp[0], pp[1]] = res
fmatrix.loc[pp[1], pp[0]] = res
手动定义p和q:
p = [[45.1024,7.7498],[45.1027,7.7513],[45.1072,7.7568],[45.1076,7.7563]]
q = [[45.0595,7.6829],[45.0595,7.6829],[45.0564,7.6820],[45.0533,7.6796],[45.0501,7.6775]]
- 第 1 步(精细)
部分代码还不错
def _c(ca, i, j, p, q):
if ca[i, j] > -1:
return ca[i, j]
elif i == 0 and j == 0:
ca[i, j] = np.linalg.norm(p[i]-q[j])
elif i > 0 and j == 0:
ca[i, j] = max(_c(ca, i-1, 0, p, q), np.linalg.norm(p[i]-q[j]))
elif i == 0 and j > 0:
ca[i, j] = max(_c(ca, 0, j-1, p, q), np.linalg.norm(p[i]-q[j]))
elif i > 0 and j > 0:
ca[i, j] = max(
min(
_c(ca, i-1, j, p, q),
_c(ca, i-1, j-1, p, q),
_c(ca, i, j-1, p, q)
),
np.linalg.norm(p[i]-q[j])
)
else:
ca[i, j] = float('inf')
return ca[i, j]
- 第 2 步(问题出在这里)是
def frdist(p, q):
# Remove nan values from p
p = np.array([i for i in p if np.any(np.isfinite(i))], np.float64) # ESSENTIAL PART TO REMOVE NaN
q = np.array([i for i in q if np.any(np.isfinite(i))], np.float64) # ESSENTIAL PART TO REMOVE NaN
len_p = len(p)
len_q = len(q)
if len_p == 0 or len_q == 0:
raise ValueError('Input curves are empty.')
# p and q no longer have to be the same length
if len(p[0]) != len(q[0]):
raise ValueError('Input curves do not have the same dimensions.')
ca = (np.ones((len_p, len_q), dtype=np.float64) * -1)
dist = _c(ca, len_p-1, len_q-1, p, q)
return(dist)
frdist(p, q)
0.09754839824415232
问题: 在第 2 步 中要做什么以将代码应用到给定的(再次是示例数据集。真实数据集非常大)数据集 df:
1 1.1 2 2.1 3 3.1 4 4.1 5 5.1
0 43.1024 6.7498 NaN NaN NaN NaN NaN NaN NaN NaN
1 46.0595 1.6829 25.0695 3.7463 NaN NaN NaN NaN NaN NaN
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 NaN NaN NaN NaN
4 35.0292 7.5616 45.0292 4.5616 23.0292 3.5616 45.0292 6.7463 NaN
通过取 p 第一行和 q 第二行。然后计算距离frdist(p, q)
。然后 p 又是第一行,但 q 现在是第三行。然后是 1 和 3.
最后我应该得到对角线为 0 的行 (rows, rows) 大小的矩阵。因为它们之间的距离是0:
0 1 2 3 4 5 ... 105
0 0
1 0
2 0
3 0
4 0
5 0
... 0
105 0
由于您的工作代码需要列表列表作为参数,因此您需要将数据框的每一行转换为列表列表,例如示例中的 p
和 q
。假设 df
是您的数据框,您可以按以下方式执行此操作:
def pairwise(it):
a = iter(it)
return zip(a, a)
ddf = df.apply(lambda x : [pair for pair in pairwise(x)], axis=1)
我从 this answer 中获取了 pairwise
函数。
ddf
是一个只有一列的数据框,每个元素都是一个列表,如 p
或 q
.
然后您需要使用行索引的组合。看看 itertools module. Depending on your needs, you can use one from product, permutations or combinations.
如果你想做每一个组合,你可以使用:
from itertools import product
idxpairs = product(ddf.index, repeat=2)
idxpairs
包含数据框中所有可能的索引对。你可以遍历它们。
您可以像这样构建最终矩阵:
fmatrix = pd.DataFrame(index=ddf.index, columns=ddf.index)
for pp in idxpairs:
fmatrix.loc[pp[0], pp[1]] = frdist(ddf.iloc[pp[0]], ddf.iloc[pp[1]])
现在这将计算暴力计算每个元素。如果你有一个大数据框并且你事先知道你的最终矩阵将具有给定的属性,比如对角线为 0 并且它是对称的(我猜 frdist(p, q) == frdist(q, p)
)你可以通过使用例如 [=23 来节省一些时间=] 而不是 product
不执行两次相同的计算:
from itertools import combinations
idxpairs = combinations(ddf.index, 2)
fmatrix = pd.DataFrame(index=ddf.index, columns=ddf.index)
for pp in idxpairs:
res = frdist(ddf.iloc[pp[0]], ddf.iloc[pp[1]])
fmatrix.loc[pp[0], pp[1]] = res
fmatrix.loc[pp[1], pp[0]] = res