【发布时间】:2019-03-29 16:14:36
【问题描述】:
假设有人想使用numpy 来向量化数组减法。例如,考虑以下设置(下面的代码):我正在计算具有给定质心的一些 (x,y) 点之间的euclidean distance。这个问题的原因是下面的示例代码正好适用于二维(x 和 y),但我想将此操作推广到 N 维以适应我的k-means algorithm .下面的代码只是计算给定质心的误差。
import numpy as np
np.random.seed(10) ## for reproducibility
x = np.random.normal(40, 10, 10)
y = np.random.normal(50, 10, 10)
data = np.array([x, y])
centroids = np.array([[25, 75], [45, 55], [20, 80], [40, 60]])
k = len(centroids)
print("\nDATA:\n{}\n\n{} CENTROIDS:\n{}\n".format(data, k, centroids))
partials = np.array([[(data[i] - centroid[i])**2 for i in range(len(data))] for centroid in centroids])
res = np.sqrt(np.sum(partials))
print("\nPARTIAL DISTANCES:\n{}\n\nTOTAL DISTANCE:\n{}\n".format(partials, res))
运行上面的代码会产生以下输出:
DATA:
[[53.31586504 47.15278974 24.54599708 39.9161615 46.21335974 32.79914439
42.65511586 41.08548526 40.04291431 38.25399789]
[54.3302619 62.03037374 40.34934329 60.28274078 52.2863013 54.45137613
38.63397788 51.35136878 64.84537002 39.20195114]]
4 CENTROIDS:
[[25 75]
[45 55]
[20 80]
[40 60]]
PARTIAL DISTANCES:
[[[8.01788213e+02 4.90746093e+02 2.06118652e-01 2.22491874e+02
4.50006631e+02 6.08266533e+01 3.11703116e+02 2.58742836e+02
2.26289271e+02 1.75668460e+02]
[4.27238073e+02 1.68211205e+02 1.20066801e+03 2.16597719e+02
5.15912109e+02 4.22245943e+02 1.32248756e+03 5.59257758e+02
1.03116510e+02 1.28150030e+03]]
[[6.91536114e+01 4.63450368e+00 4.18366235e+02 2.58454139e+01
1.47224186e+00 1.48860878e+02 5.49848164e+00 1.53234257e+01
2.45726985e+01 4.55085444e+01]
[4.48549123e-01 4.94261549e+01 2.14641742e+02 2.79073501e+01
7.36416063e+00 3.00988153e-01 2.67846680e+02 1.33125097e+01
9.69313108e+01 2.49578348e+02]]
[[1.10994686e+03 7.37273991e+02 2.06660894e+01 3.96653489e+02
6.87140229e+02 1.63818097e+02 5.13254274e+02 4.44597689e+02
4.01718414e+02 3.33208439e+02]
[6.58935454e+02 3.22907468e+02 1.57217458e+03 3.88770311e+02
7.68049096e+02 6.52732182e+02 1.71114779e+03 8.20744071e+02
2.29662810e+02 1.66448079e+03]]
[[1.77312262e+02 5.11624011e+01 2.38826206e+02 7.02889396e-03
3.86058392e+01 5.18523215e+01 7.04964021e+00 1.17827824e+00
1.84163795e-03 3.04852335e+00]
[3.21459301e+01 4.12241752e+00 3.86148309e+02 7.99423486e-02
5.95011476e+01 3.07872269e+01 4.56506901e+02 7.47988219e+01
2.34776106e+01 4.32558836e+02]]]
TOTAL DISTANCE:
163.00230640508593
我在这段代码中使用了嵌套的双 for 循环。我注意到numpy.subtract 没有axis kwarg。我在想我可以numpy.tile 质心来执行减法,但这对于大 N 来说似乎效率低下,特别是如果需要多次迭代才能收敛。有没有不同的方法来矢量化这个操作?
【问题讨论】:
-
所以
data是 (2,10) 形状,centroids(4,2) 和partials(4,2,10)。如果centroids扩展为 (4,2,1),则广播会处理其余部分。 -
data - centroids[:,:,None]
标签: python-3.x numpy for-loop vector vectorization