noob
noob

Reputation: 778

Inserting rows in an empty array using Numpy

Hello im currently trying to convert this array

test=np.array([[0,0],[0,1],[1,1],[3,0]])

and using Manhattan distance to convert this array into this shape

[0., 1., 2., 3.] 
[1., 0., 1., 4.]
[2., 1., 0., 3.,
[3., 4., 3., 0.]

the code goes like this

list_x=[]
newarray=np.array([])
length=len(test)
for i in range(length):
    for j in range(length):
        print('i=',i)
        print('j=',j)
        var=sum(abs(a-b) for a,b in zip(test[i],test[j]))
        list_x.append(var)
    newarray= np.append(newarray,list_x,axis = 0) 
    list_x=[]
    

but the outcome of the code keeps giving me this:

array([0., 1., 2., 3., 1., 0., 1., 4., 2., 1., 0., 3., 3., 4., 3., 0.])

is there a problem in my np.append() that prevent to convert it to 4*4 shap array ?

Upvotes: 2

Views: 117

Answers (2)

Ehsan
Ehsan

Reputation: 12397

Another way of doing it is using Scipy:

from scipy.spatial.distance import cdist
cdist(test,test,'cityblock')

output:

[[0. 1. 2. 3.]
 [1. 0. 1. 4.]
 [2. 1. 0. 3.]
 [3. 4. 3. 0.]]

Comparison:

#@ehsan's solution
def m1(test):
  return cdist(test,test,'cityblock')

#@yatu's solution
def m2(test):
  return manhattan_distances(test)

in_ = [np.random.randint(0,10,(n,2)) for n in [10,100,1000,10000]]

For large arrays they seem to have similar performance, but for smaller array (around 1000 rows) m1 seems faster.

enter image description here

Upvotes: 0

yatu
yatu

Reputation: 88226

You could go with scikit-learn's manhattan_distances to obtain all pairwise manhattan distances simplifying the above to a single function call:

from sklearn.metrics.pairwise import manhattan_distances

manhattan_distances(test)
array([[0., 1., 2., 3.],
       [1., 0., 1., 4.],
       [2., 1., 0., 3.],
       [3., 4., 3., 0.]])

If you wanted to obtain the distance with a for loop, I'd suggest you to use python lists instead. In order to end up with a nested list, generate an inner list with the distances of a row to the others, and append it to an outer list on each iteration:

out=[]
for i in range(length):
    new_row = []
    for j in range(length):
        var=sum(abs(a-b) for a,b in zip(test[i],test[j]))
        new_row.append(var)
    out.append(new_row)

print(out)
# [[0, 1, 2, 3], [1, 0, 1, 4], [2, 1, 0, 3], [3, 4, 3, 0]]

Upvotes: 1

Related Questions