我知道scipy.spatial.distance.pdist函数以及如何从所得的矩阵/ ndarray计算均值。
>>> x = np.random.rand(10000, 2)
>>> y = pdist(x, metric='euclidean')
>>> y.mean()
0.5214255824176626
在上面的示例中,y
变得很大(几乎是输入数组的2500倍):
>>> y.shape
(49995000,)
>>> from sys import getsizeof
>>> getsizeof(x)
160112
>>> getsizeof(y)
399960096
>>> getsizeof(y) / getsizeof(x)
2498.0019986009793
但是因为我只对平均成对距离感兴趣,所以距离矩阵不必保存在内存中。而是可以分别计算每一行(或每一列)的平均值。然后可以从行平均值计算出最终平均值。
是否已经有一个利用此属性的函数,或者有一种简单的方法来扩展/合并现有函数呢?
答案 0 :(得分:1)
如果使用距离的平方形式,则相当于使用n-1的方差:
from scipy.spatial.distance import pdist, squareform
import numpy as np
x = np.random.rand(10000, 2)
y = np.array([[1,1], [0,0], [2,0]])
print(pdist(x, 'sqeuclidean').mean())
print(np.var(x, 0, ddof=1).sum()*2)
>>0.331474285845873
0.33147428584587346
答案 1 :(得分:0)
您将必须按构成平均值的观察数对每一行加权。例如,一个3 x 2矩阵的pdist是正方形3 x 3距离矩阵的平坦上三角(偏移量为1)。
arr = np.arange(6).reshape(3,2)
arr
array([[0, 1],
[2, 3],
[4, 5]])
pdist(arr)
array([2.82842712, 5.65685425, 2.82842712])
from sklearn.metrics import pairwise_distances
square = pairwise_distances(arr)
square
array([[0. , 2.82842712, 5.65685425],
[2.82842712, 0. , 2.82842712],
[5.65685425, 2.82842712, 0. ]])
square[triu_indices(square.shape[0], 1)]
array([2.82842712, 5.65685425, 2.82842712])
有一个pairwise_distances_chuncked
函数可用于逐行遍历距离矩阵,但是您需要跟踪行索引以确保仅取上层值的平均值/矩阵的下三角(距离矩阵是对称的)。这并不复杂,但是我想您会带来明显的减速。
tot = ((arr.shape[0]**2) - arr.shape[0]) / 2
weighted_means = 0
for i in gen:
if r < arr.shape[0]:
sm = i[0, r:].mean()
wgt = (i.shape[1] - r) / tot
weighted_means += sm * wgt
r += 1