- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我博士期间的一个副业项目中,我参与了用 Python 对一些系统进行建模的任务。在效率方面,我的程序在以下问题中遇到了瓶颈,我将在一个最小工作示例中公开该问题。
我处理大量由 3D 起点和终点编码的片段,因此每个片段由 6 个标量表示。
我需要计算成对的最小段间距离。两个段之间的最小距离的解析表达式在这个 source 中找到.致 MWE:
import numpy as np
N_segments = 1000
List_of_segments = np.random.rand(N_segments, 6)
Pairwise_minimal_distance_matrix = np.zeros( (N_segments,N_segments) )
for i in range(N_segments):
for j in range(i+1,N_segments):
p0 = List_of_segments[i,0:3] #beginning point of segment i
p1 = List_of_segments[i,3:6] #end point of segment i
q0 = List_of_segments[j,0:3] #beginning point of segment j
q1 = List_of_segments[j,3:6] #end point of segment j
#for readability, some definitions
a = np.dot( p1-p0, p1-p0)
b = np.dot( p1-p0, q1-q0)
c = np.dot( q1-q0, q1-q0)
d = np.dot( p1-p0, p0-q0)
e = np.dot( q1-q0, p0-q0)
s = (b*e-c*d)/(a*c-b*b)
t = (a*e-b*d)/(a*c-b*b)
#the minimal distance between segment i and j
Pairwise_minimal_distance_matrix[i,j] = sqrt(sum( (p0+(p1-p0)*s-(q0+(q1-q0)*t))**2)) #minimal distance
现在,我意识到这是极其低效的,这就是我来这里的原因。我已经广泛研究了如何避免循环,但遇到了一些问题。显然,这种计算最好用 cdist 完成。 python 。但是,它可以处理的自定义距离函数必须是二元函数。这在我的例子中是个问题,因为我的向量的长度特别是 6,并且必须按位拆分成它们的前 3 个分量和后 3 个分量。我不认为我可以将距离计算转化为二元函数。
欢迎任何意见。
最佳答案
您可以使用 numpy 的向量化功能来加速计算。我的版本一次计算距离矩阵的所有元素,然后将对角线和下三角设置为零。
def pairwise_distance2(s):
# we need this because we're gonna divide by zero
old_settings = np.seterr(all="ignore")
N = N_segments # just shorter, could also use len(s)
# we repeat p0 and p1 along all columns
p0 = np.repeat(s[:,0:3].reshape((N, 1, 3)), N, axis=1)
p1 = np.repeat(s[:,3:6].reshape((N, 1, 3)), N, axis=1)
# and q0, q1 along all rows
q0 = np.repeat(s[:,0:3].reshape((1, N, 3)), N, axis=0)
q1 = np.repeat(s[:,3:6].reshape((1, N, 3)), N, axis=0)
# element-wise dot product over the last dimension,
# while keeping the number of dimensions at 3
# (so we can use them together with the p* and q*)
a = np.sum((p1 - p0) * (p1 - p0), axis=-1).reshape((N, N, 1))
b = np.sum((p1 - p0) * (q1 - q0), axis=-1).reshape((N, N, 1))
c = np.sum((q1 - q0) * (q1 - q0), axis=-1).reshape((N, N, 1))
d = np.sum((p1 - p0) * (p0 - q0), axis=-1).reshape((N, N, 1))
e = np.sum((q1 - q0) * (p0 - q0), axis=-1).reshape((N, N, 1))
# same as above
s = (b*e-c*d)/(a*c-b*b)
t = (a*e-b*d)/(a*c-b*b)
# almost same as above
pairwise = np.sqrt(np.sum( (p0 + (p1 - p0) * s - ( q0 + (q1 - q0) * t))**2, axis=-1))
# turn the error reporting back on
np.seterr(**old_settings)
# set everything at or below the diagonal to 0
pairwise[np.tril_indices(N)] = 0.0
return pairwise
现在让我们试一试。在你的例子中,N = 1000
,我得到了一个时间
%timeit pairwise_distance(List_of_segments)
1 loops, best of 3: 10.5 s per loop
%timeit pairwise_distance2(List_of_segments)
1 loops, best of 3: 398 ms per loop
当然,结果是一样的:
(pairwise_distance2(List_of_segments) == pairwise_distance(List_of_segments)).all()
返回 True
。我也很确定算法中某处隐藏了一个矩阵乘法,因此应该有进一步加速(以及清理)的潜力。
顺便说一句:我试过先简单地使用 numba 但没有成功。不过不知道为什么。
关于Python,Pairwise 'distance',需要一种快速的方法来完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28693494/
我手头有一道算法题。为了容易解释这个问题,我将使用一个简单的类比。我有一个输入文件 Country,Exports Austrailia,Sheep US, Apple Austrialia,Beef
我正在尝试为垂直和水平滚动方向创建两个可观察的滚动事件。 我尝试使用 pairwise() 和 bufferCount(2,1) 运算符从水平滚动事件中过滤垂直滚动事件,但问题是获取重复值prev.s
我有一个类似于 itertools 的 pairwise 配方的生成器,它生成 (s0,s1), (s1,s2), (s2, s3)...。我想从中创建另一个生成器,生成原始序列 s0, s1, s2
itertools 的文档提供了一个 recipe对于 pairwise() 函数,我在下面稍作修改,使其返回 (last_item, None) 作为最后一对: from itertools imp
在我博士期间的一个副业项目中,我参与了用 Python 对一些系统进行建模的任务。在效率方面,我的程序在以下问题中遇到了瓶颈,我将在一个最小工作示例中公开该问题。 我处理大量由 3D 起点和终点编码的
这是测试的正常输出: attach(airquality) pw <- pairwise.wilcox.test(Ozone, Month, p.adj = "bonf") pw data: Ozo
我有一个二进制字符串,其中字节按以下方式反转:该文件包含例如四个字节0x18 0xb1 0x35 0x41,应解释为0xb1 0x18 0x41 0x35 code> 到我的 Perl 字符串或数组中
我有一个二进制字符串,其中字节按以下方式反转:该文件包含例如四个字节0x18 0xb1 0x35 0x41,应解释为0xb1 0x18 0x41 0x35 code> 到我的 Perl 字符串或数组中
如何成对迭代 groupby 结果?我尝试的方法不太奏效: from itertools import groupby,izip groups = groupby([(1,2,3),(1,2),(1,
所以我正在尝试做一个成对表并保留每对的 p 值。请注意,我仍然是 R 的初学者。我的数据看起来像这样(虽然大得多): a % gather(.,key="variable",value="value
将 pysal 导入为 ps 我正在尝试导入 pysal,但我得到以下信息: 无法从“sklearn.metrics.pairwise”导入名称“haversine_distances” 所以我尝试了
我使用 XGBoost 的 python 实现。目标之一是rank:pairwise并且最小化成对损失( Documentation )。但是,它没有说明输出的范围。我看到 -10 到 10 之间的数
我想用一个简单(但糟糕)的数据集做一个简单的成对 wilcox 测试。我有 8 个组,每个组有 5 个值(见下面的数据)。这些组位于“id”列中,感兴趣的变量(在本例中为权重)位于“weight”中。
假设我有一个像这样的矩阵: [[5.05537647 4.96643654 4.88792309 4.48089566 4.4469417 3.7841264] [4.81800568 4.7552
我已经进行了一系列成对比较(准确地说是 241 x 241)。 生成的文件如下所示: A,X,10 A,Y,20 X,Y,15 我想将其转换为一个表格,显示所有成对比较。 IE。像这样的东西 ,A,X
我正在使用 sklearn 的成对距离函数,它在计算巨大矩阵时救了我的命,但我遇到的问题是我丢失了索引。具体来说,我最初有一个 17000 x 300 的巨大数据帧,我根据某些类条件将其分解为 4 个
我正在做一些行为分析,我会随着时间的推移跟踪行为,然后创建这些行为的 n-gram。 sample_n_gram_list = [['scratch', 'scratch', 'scratch', '
我有一个如下所示的数据框: id name 0 12 molly 1 12 james 2 10 adam 3 8 susa
我有一个名为“df”的数据框,如下所示: ID Value 1 a 1 b 1 c 1 d 3 a 3 b 3 e 3 f . . . . . . 我有一
n = int(input()) a = [int(x) for x in input().split()] product = 0 for i in range(n): for j in ran
我是一名优秀的程序员,十分优秀!