一般來說,我是 numpy 的新手,所以這是一個簡單的問題,但我不知道如何解決它。
我正在嘗試實作 K 最近鄰演算法來分類資料集
有名為new_points和point的陣列分別具有(30,4) 和 (120,4)的形狀(其中 4 是每個元素的屬性總數)
所以我試圖計算每個元素之間的距離使用numpy.broadcasting的新點和所有舊點
def calc_no_loop(new_points, points):
return np.sum((new_points-points)**2,axis=1)
#doesn't work here is log
ValueError:運算元無法與形狀一起廣播 (30,4) (120,4)
但是,根據廣播兩個形狀陣列 (30,4) 和 (120,4) 的規則是不兼容的,所以我將不勝感激有關如何解決這個問題的任何見解(使用 .reshape prehaps - 不確定)
請注意:我已經使用一個和兩個回圈實作了相同的功能,但沒有一個就無法實作
def calc_two_loops(new_points, points):
m, n = len(new_points), len(points)
d = np.zeros((m, n))
for i in range(m):
for j in range(n):
d[i, j] = np.sum((new_points[i] - points[j])**2)
return d
def calc_one_loop(new_points, points):
m, n = len(new_points), len(points)
d = np.zeros((m, n))
print(d)
for i in range(m):
d[i] = np.sum((new_points[i] - points)**2)
return d
uj5u.com熱心網友回復:
讓我們創建一個較小的示例:
nNew = 3; nOld = 5 # Number of new / old points
# New points
new_points = np.arange(100, 100 nNew * 4).reshape(nNew, 4)
# Old points
points = np.arange(10, 10 nOld * 8, 2).reshape(nOld, 4)
要單獨計算差異,請運行:
dfr = new_points[:, np.newaxis, :] - points[np.newaxis, :, :]
到目前為止,我們在每個點的每個屬性上都有差異(每個新點與每個舊點)。
dfr的形狀是(3, 5, 4):
- 第一維:新點的數量,
- 第二維:老點數,
- 第三個維度:每個屬性的差異。
然后,按點求差平方和,運行:
d = np.power(dfr, 2).sum(axis=2)
這就是你的結果。
對于我的樣本資料,結果是:
array([[31334, 25926, 21030, 16646, 12774],
[34230, 28566, 23414, 18774, 14646],
[37254, 31334, 25926, 21030, 16646]], dtype=int32)
uj5u.com熱心網友回復:
所以你有 30 個新點和 120 個舊點,所以如果我理解正確,你想要一個 shape(120,30) 距離陣列結果。
你可以做
import numpy as np
points = np.random.random(120*4).reshape(120,4)
new_points = np.random.random(30*4).reshape(30,4)
def calc_no_loop(new_points, points):
res = np.zeros([len(points[:,0]),len(new_points[:,0])])
for idx in range(len(points[:,0])):
res[idx,:] = np.sum((points[idx,:]-new_points)**2,axis=1)
return np.sqrt(res)
test = calc_no_loop(new_points,points)
print(np.shape(test))
print(test)
這使
(120, 30)
[[0.67166838 0.78096694 0.94983683 ... 1.00960301 0.48076185 0.56419991]
[0.88156338 0.54951826 0.73919191 ... 0.87757896 0.76305462 0.52486626]
[0.85271938 0.56085692 0.73063341 ... 0.97884167 0.90509791 0.7505591 ]
...
[0.53968258 0.64514941 0.89225849 ... 0.99278462 0.31861253 0.44615026]
[0.51647526 0.58611128 0.83298535 ... 0.86669406 0.64931403 0.71517123]
[1.08515826 0.64626221 0.6898687 ... 0.96882542 1.08075076 0.80144746]]
但是從您上面的函式名稱中,我得到了您不想要回圈的概念?然后你可以這樣做:
def calc_no_loop(new_points, points):
new_points1 = np.repeat(new_points[np.newaxis,...],len(points),axis=0)
points1 = np.repeat(points[:,np.newaxis,:],len(new_points),axis=1)
return np.sqrt(np.sum((new_points-points1)**2 ,axis=2))
test = calc_no_loop(new_points,points)
print(np.shape(test))
print(test)
有輸出:
(120, 30)
[[0.67166838 0.78096694 0.94983683 ... 1.00960301 0.48076185 0.56419991]
[0.88156338 0.54951826 0.73919191 ... 0.87757896 0.76305462 0.52486626]
[0.85271938 0.56085692 0.73063341 ... 0.97884167 0.90509791 0.7505591 ]
...
[0.53968258 0.64514941 0.89225849 ... 0.99278462 0.31861253 0.44615026]
[0.51647526 0.58611128 0.83298535 ... 0.86669406 0.64931403 0.71517123]
[1.08515826 0.64626221 0.6898687 ... 0.96882542 1.08075076 0.80144746]]
即相同的結果。請注意,我將 np.sqrt() 添加到您可能在上面的示例中忘記的結果中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/430707.html
上一篇:矩陣預處理的錯誤元組索引超出范圍
