somoclu to produce an emergent Self-Organising Map of some data. Once I have the BMUs (Best Matching Units) I'm performing a Delaunay Triangulation on the co-ordinates of the BMUs in order to find each BMU's neighbours in the SOM.
In the following snippet of Python, is there a more Pythonic version of the
a == c and b == d conditional? In other words, how can I compare
point directly without splitting out the separate co-ordinates?
points = np.unique(np.array(som.bmus), axis = 0) for idx, bmu in enumerate(som.bmus): a, b = bmu for point_idx, point in enumerate(points): c, d = point if a == c and b == d: # More Pythonic version of this line? print (idx, point_idx) breakAnswer1:
We are working with NumPy arrays, so we can leverage <a href="https://docs.scipy.org/doc/numpy-1.13.0/user/basics.broadcasting.html" rel="nofollow">
broadcasting</a> for a vectorized solution -
ar = np.array(som.bmus) points = np.unique(ar, axis = 0) mask = (ar[:,0,None]==points[:,0]) & (ar[:,1,None]==points[:,1]) indices = np.argwhere(mask)
One more compact way to get
mask, which covers for a generic no. of columns in
ar, would be -
mask = (ar[:,None] == points).all(axis=2)
Another memory-efficient approach for generic no. of cols would be with
views and <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.searchsorted.html" rel="nofollow">
# https://stackoverflow.com/a/45313353/ @Divakar def view1D(a, b): # a, b are arrays a = np.ascontiguousarray(a) b = np.ascontiguousarray(b) void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape)) return a.view(void_dt).ravel(), b.view(void_dt).ravel() n = len(ar) indices = np.empty((n,2),dtype=int) indices[:,0] = np.arange(n) a,b = view1D(ar, points) # ar, points from app#1 indices[:,1] = np.searchsorted(b, a)Answer2:
numpy arrays, you can use <a href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.array_equal.html" rel="nofollow">
np.array_equal</a>. This tests for same shape and same elements.
But if your logic is as simple as the code you have, use <a href="https://stackoverflow.com/a/49731025/9209546" rel="nofollow">@Divakar's vectorized solution</a>.
points = np.unique(np.array(som.bmus), axis = 0) for idx, bmu in enumerate(som.bmus): for point_idx, point in enumerate(points): if np.array_equal(bmu, point): print(idx, point_idx) break