Reputation: 7261
I am trying to create a loop that will allow me to loop through both numpy arrays and floats, specifically, ndarray and float64.
My current code is:
def euclidean_distance(a, b):
print (type(a))
print (type(b))
total_distance = 0
for index in range(len(a)):
total_distance = total_distance + ((a[index] - b[index])*(a[index] - b[index]))
total_distance = math.sqrt(total_distance)
return total_distance
My output is:
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
<class 'numpy.float64'>
<class 'numpy.float64'>
Traceback (most recent call last):
File "D:/ML/WiP_KMeans.py", line 289, in <module>
main()
File "D:/ML/WiP_KMeans.py", line 286, in main
k_means(test, 3)
File "D:/ML/WiP_KMeans.py", line 239, in k_means
centroid_error = centroid_error + get_centroid_error(currCent , oldCent)
File "D:/ML/WiP_KMeans.py", line 70, in get_centroid_error
total_error = total_error + euclidean_distance(centroid[index], old_centroid[index])
File "D:/ML/WiP_KMeans.py", line 48, in euclidean_distance
for index in range(len(a)):
TypeError: object of type 'numpy.float64' has no len()
I have tried using different variations of nditer
from numpy documentation, but have not found a solution that will allow me to properly iterate either an ndarray or a float to calculate Euclidean Distance.
An example of a normal input can be something like a=[0.3, 5.4, 3.2, 11.0] and b=[0.0, 5.0, 31.3, 2.0]
.
I have included some examples, here:
[5.9, 3.0, 5.1, 1.8] - [5.1, 3.3, 1.7, 0.5]
[5.9, 3.0, 5.1, 1.8] - [4.8, 3.4, 1.9, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.0, 1.6, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.4, 1.6, 0.4]
[5.9, 3.0, 5.1, 1.8] - [5.2, 3.5, 1.5, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.2, 3.4, 1.4, 0.2]
[5.9, 3.0, 5.1, 1.8] - [4.7, 3.2, 1.6, 0.2]
[5.9, 3.0, 5.1, 1.8] - [4.8, 3.1, 1.6, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.4, 3.4, 1.5, 0.4]
[5.9, 3.0, 5.1, 1.8] - [5.2, 4.1, 1.5, 0.1]
[5.9, 3.0, 5.1, 1.8] - [4.9, 3.1, 1.5, 0.1]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.2, 1.2, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.5, 3.5, 1.3, 0.2]
[5.9, 3.0, 5.1, 1.8] - [4.9, 3.1, 1.5, 0.1]
[5.9, 3.0, 5.1, 1.8] - [4.4, 3.0, 1.3, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.1, 3.4, 1.5, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.5, 1.3, 0.3]
[5.9, 3.0, 5.1, 1.8] - [4.5, 2.3, 1.3, 0.3]
[5.9, 3.0, 5.1, 1.8] - [4.4, 3.2, 1.3, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.5, 1.6, 0.6]
[5.9, 3.0, 5.1, 1.8] - [5.1, 3.8, 1.9, 0.4]
[5.9, 3.0, 5.1, 1.8] - [4.8, 3.0, 1.4, 0.3]
[5.9, 3.0, 5.1, 1.8] - [5.1, 3.8, 1.6, 0.2]
[5.9, 3.0, 5.1, 1.8] - [4.6, 3.2, 1.4, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.3, 3.7, 1.5, 0.2]
[5.9, 3.0, 5.1, 1.8] - [5.0, 3.3, 1.4, 0.2]
[5.9, 3.0, 5.1, 1.8] - [4.9, 2.4, 3.3, 1.0]
[5.9, 3.0, 5.1, 1.8] - [5.0, 2.0, 3.5, 1.0]
[5.9, 3.0, 5.1, 1.8] - [5.0, 2.3, 3.3, 1.0]
[5.9, 3.0, 5.1, 1.8] - [5.1, 2.5, 3.0, 1.1]
[5.488288288288287] - [6.4]
Can anybody assist?
Upvotes: 0
Views: 87
Reputation: 16593
This operation can be fully vectorized (no Python for loops needed, massive performance increase):
a = np.array([0.3, 5.4, 3.2, 11.0])
b = np.array([0.0, 5.0, 31.3, 2.0])
np.sqrt(np.sum((a - b) ** 2))
Howver, NumPy comes with batteries included. There is a function for this:
np.linalg.norm(a - b)
Similar performance should be expected from both methods. The second is probably faster, though.
Upvotes: 3
Reputation: 196
Here is an example that should work for you.
import numpy as np
a=np.array([0.3, 5.4, 3.2, 11.0])
b=np.array([0.0, 5.0, 31.3, 2.0])
c=np.array([0.1])
d=np.array([6.2])
def dist(x,y):
return np.sqrt(sum([(x[i]-y[i])**2 for i in range(x.shape[0])]))
print(dist(a,b))
print(dist(c,d))
Upvotes: 0