Q:

Pandas : transform a 2D dataframe to a 3D one

I have a Pandas dataframe like :
     p1 p2 p3
t1   a  b  c
t2   d  e  f
t3   g  h  i

and I want either several df (or one xarray), one for each t(y axis)
like:
for t1: the value of pn minus pn for t1 :
     p1    p2   p3
p1   a-a  b-a  c-a 
p2   a-b  b-b  c-b
p3   a-c  b-c  c-c

idem for t2, t3 and so on...
I have made a loop like
for t in tlist :
    for p in plist :
        for q in plist :
            res = p - q

but it's hugly and slow.
So if anyone know a pythonic way to do that, [s]he's very welcome !

A:

This can be done in a quite simple manner leveraging numpy's broadcasting. Let's try with the following ndarray:
a = np.random.randint(1,10,(3,3))

print(a)
array([[9, 6, 4],
       [2, 3, 6],
       [8, 9, 2]])

a[:,None] - a[...,None]

array([[[ 0, -3, -5],
        [ 3,  0, -2],
        [ 5,  2,  0]],

       [[ 0,  1,  4],
        [-1,  0,  3],
        [-4, -3,  0]],

       [[ 0,  1, -6],
        [-1,  0, -7],
        [ 6,  7,  0]]])

This works by adding new axes to the arrays in such a way, that subtracting them yields the desired cartesian operation, since:
print(a[:,None])

array([[[9, 6, 4]],

       [[2, 3, 6]],

       [[8, 9, 2]]])

print(a[...,None])

array([[[9],
        [6],
        [4]],

       [[2],
        [3],
        [6]],

       [[8],
        [9],
        [2]]])

