I have a execution speed problem with my code. The following code tries to calculate the nearest neighbor rows of the each row of a matrix. The metric for the distance calculation is Euclidian distance based on a near neighbor exclusion constraint. At the end, I need the row numbers of 8 nearest neighbors for each row of the matrix.
The input matrix (EmbedMat) is a segmented version of the time series data. Like:
Here is the following working example. Buffer is the custom function to create EmbedMat.
import numpy as np
def buffer(data,num_perseg,overlap):
numberOfSegments = int(math.ceil((len(data)-overlap)/(num_perseg-overlap)))
tempBuf = [data[i:i+num_perseg] for i in range(0,len(data),(num_perseg-int(overlap)))]
tempBuf[numberOfSegments-1] = np.pad(tempBuf[numberOfSegments-1],(0,num_perseg-tempBuf[numberOfSegments-1].shape[0]),'constant')
tempBuf2 = np.vstack(tempBuf[0:numberOfSegments])
return tempBuf2
EmbedMat=buffer(np.arange(0,50),5,4)
def distance_calculator(EmbedMat,E=5,nn=8):
# Calculates the Euclidian distance of the rows of embedded matrix
# subjecting it to a near-in-time neighbour exclusion constraint
# abs(jp-i)>E/2
bins=np.arange(0,EmbedMat.shape[0])
# calculate all possible combinations of rows
bin_comb=[(x,y) for x in bins for y in bins]
count=0
dist=np.zeros((EmbedMat.shape[0]*EmbedMat.shape[0],))
for i in bin_comb:
if abs(i[0]-i[1])>E/2:
# without numpy.linalg.norm library, execution time is less.
dist[count]=math.sqrt(((EmbedMat[i[0],:]-EmbedMat[i[1],:])**2).sum())
else:
dist[count]=np.NAN
count=count+1
dist_buf=buffer(dist,EmbedMat.shape[0],0)
dist_buf=dist_buf[:,0:EmbedMat.shape[0]-1]
# distance from x/row to y/col
# i.e [4,5] represents the distance(row4,row5) of EmbedMat
sortIndex=np.argsort(dist_buf,axis=1)
sort_red=sortIndex[:,0:nn]
return sort_red
sort_red=distance_calculator(EmbedMat)
Works good with 50 samples but the execution time gets worse (up to 5-7 seconds) if the sample length is 1000 and more.
I am relatively new to Python and NOT coming from a developer background, so that you may not see good coding practices in the codes above. Sorry for the mess you see.
Any help will be appreciated.