我有一个由几个点的x,y,z坐标组成的矩阵。我想找到极值点,即最远的两个点。
我可以在matlab中找到一种方法,但我需要它在Python中
这是matlab中的代码
A = randint(500,3,[-5 5]);
D=pdist(A);
D=squareform(D);
[N,I]=max(D(:));
[I_row, I_col] = ind2sub(size(D),I);
pdist给出点对之间的距离(i,j)。 squareform给出矩阵输出 在最后两个步骤中,我尝试找到矩阵I_row,I_col ..
的索引点I_row和I_col有最大距离..
任何人都可以在python中建议我一个有效的方法,因为我所有的其他代码都是用Python编写的。
答案 0 :(得分:5)
这里所有其他答案都花费 O(N ^ 2)的时间和空间。太可怕了。
相反,要认识到数据集中的两个最远点位于集合的凸包上。由于可以在3D中以 O(N log N)时间计算船体,因此可以形成有效的预过滤器。在我对具有16,000,000点的数据集的测试中,凸包仅包含420点。
可以在 O(H log H)时间找到船体上最远的点,尽管这在Python中很难实现。因此,我们可以在那时转回 O(N ^ 2) cdist解决方案。
import numpy as np
from scipy.spatial import ConvexHull
from scipy.spatial.distance import cdist
N = 16000000
# Find a convex hull in O(N log N)
points = np.random.rand(N, 3) # N random points in 3-D
# Returned 420 points in testing
hull = ConvexHull(points)
# Extract the points forming the hull
hullpoints = points[hull.vertices,:]
# Naive way of finding the best pair in O(H^2) time if H is number of points on
# hull
hdist = cdist(hullpoints, hullpoints, metric='euclidean')
# Get the farthest apart points
bestpair = np.unravel_index(hdist.argmax(), hdist.shape)
#Print them
print([hullpoints[bestpair[0]],hullpoints[bestpair[1]]])
答案 1 :(得分:4)
如果你有scipy
,那么对于大多数matlab核心函数你都具有相同的等价物:
from numpy import random, nanmax, argmax, unravel_index
from scipy.spatial.distance import pdist, squareform
A = random.randint(-5,5, (500,3))
D = pdist(A)
D = squareform(D);
N, [I_row, I_col] = nanmax(D), unravel_index( argmax(D), D.shape )
你也可以使用itertools
:
from itertools import combinations
from random import randint
A = [[randint(-5,5) for coord in range(3)] for point in range(500)]
def square_distance(x,y): return sum([(xi-yi)**2 for xi, yi in zip(x,y)])
max_square_distance = 0
for pair in combinations(A,2):
if square_distance(*pair) > max_square_distance:
max_square_distance = square_distance(*pair)
max_pair = pair
答案 2 :(得分:3)
这将为您提供A中与temp_b相距最远的点的索引对。请注意,它将包括列表中的两个方向,例如(8,222)和(222,8)。如果你愿意,我会留给你删除它们。
import numpy as np
import random as rd
from scipy.spatial.distance import pdist
from scipy.spatial.distance import squareform
A = np.array([np.array([rd.randint(-5,5) for x in range(3)]) for y in range(500)])
D=pdist(A)
D=squareform(D)
temp = np.where(D == D.max())
temp_b = zip(temp[0],temp[1])
答案 3 :(得分:0)
您可以使用scipy的pdist
import numpy as np
from scipy.spatial.distance import pdist, squareform
A = np.random.randint(-5, 5, [500, 3])
D = squareform(pdist(A))
N = np.max(D)
I = np.argmax(D)
I_row, I_col = np.unravel_index(I, D.shape)