I have some geospatial data and I am trying to produce pairwise haversine distances between points. Unfortunately, there are around 50k data points, which will produce a 50000x50000 distance matrix. Since this distance matrix is symmetric, I was thinking that this matrix could be sparse. I would like to be able to produce a sparse matrix straight from the distance computation, so I don't get memory errors. Here is my code so far:
def convert_to_arrays(df1, df2):
d1 = np.array(df1[['x','y']].values.tolist())
d2 = np.array(df2[['x','y']].values.tolist())
return d1,d2
def haversine(data1, data2):
data1 = np.deg2rad(data1)
data2 = np.deg2rad(data2)
lat1 = data1[:,0]
lng1 = data1[:,1]
lat2 = data2[:,0]
lng2 = data2[:,1]
diff_lat = lat1[:,None] - lat2
diff_lng = lng1[:,None] - lng2
d = np.sin(diff_lat/2)**2 + np.cos(lat1[:,None])*np.cos(lat2) * np.sin(diff_lng/2)**2
return 2 * 6371 * np.arcsin(np.sqrt(d))
dist = haversine(*convert_to_arrays(df, df))
Where df is a pandas data frame with columns 'x' and 'y'. When I run this code with around 50k points, I get a memory error:
MemoryError: Unable to allocate 19.3 GiB for an array with shape (50893, 50893) and data type float64
Is there a way to ensure that the calculation is performed with a (lower or upper triangular) sparse matrix as the intended output?
A = scipy.sparse.csr_matrix((50893,50893), dtype=np.float32).toarray(). I want to be able to compute a sparse lower triangular distance matrix from the start without having to compute a dense matrix first. - CopyOfAscipy.distanceuses a compressed distance matrix representation for this. Basically, you're just storing a 1d array of distances where entries correspond to[dist(x[0], x[1]), dist(x[0], x[2]), ..., dist(x[0], x[n]), dist(x[1], x[2]), dist(x[1], x[3]), ..., dist(x[n-1], x[n])]. @CopyOfA, I don't believescipyhas any sparse matrix format that does what you want. - ivirshup