I have an array: U = np.array([3, 5, 7, 9, 11])  I want to get a result like: result = np.array([ [ np.nan, np.nan, np.nan, np.nan, np.nan], [U[0] - U[1], np.nan, np.nan, np.nan, np.nan], [U[0] - U[2], U[1] - U[2], np.nan, np.nan, np.nan], [U[0] - U[3], U[1] - U[3], U[2] - U[3], np.nan, np.nan], [U[0] - U[4], U[1] - U[4], U[2] - U[4], U[3] - U[4], np.nan] ])  I can use np.tril_indices(4, k=-1) to get indices of lower triangle without diagonal, but what is next?
A naive approach that does more work than necessary is to compute the entire difference and select the elements you need: np.where(np.arange(U.size)[:, None] > np.arange(U.size), U[:, None] - U, np.nan)  This is one of the times where np.where is actually useful over a simple mask, although it can be done with a mask as well: result = np.full((U.size, U.size), np.nan) index = np.arange(U.size) mask = index[:, None] > index result[mask] = [U[:, None] - U][mask]  A more efficient approach might be to use the indices more directly to index into the source: result = np.full((U.size, U.size), np.nan) r, c = np.tril_indices(U.size, k=-1) result[r, c] = U[c] - U[r] 