We want to get indices for the upper and lower triangles of a square matrix. Or, in other words, where the identity matrix is ββzero
np.eye(len(df))
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
So I subtract it from 1 and
array([[ 0., 1., 1.],
[ 1., 0., 1.],
[ 1., 1., 0.]])
In a boolean context and passed in np.where
, I get exactly the top and bottom indices of the triangle.
i, j = np.where(1 - np.eye(len(df)))
df.iloc[i].reset_index(drop=True).join(
df.iloc[j].reset_index(drop=True), rsuffix='_2')
id value id_2 value_2
0 1 a 2 b
1 1 a 3 c
2 2 b 1 a
3 2 b 3 c
4 3 c 1 a
5 3 c 2 b