Often, Hamiltonians for spin-systems are given in terms of the four Pauli-matrices

$$ \newcommand{\trace}{\operatorname{tr}} \newcommand{\diag}{\operatorname{diag}} \sigma_1 = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix},\quad \sigma_x = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix},\quad \sigma_y = \begin{pmatrix} 0 &-i \\ i & 0 \end{pmatrix},\quad \sigma_z = \begin{pmatrix} 1 & 0 \\ 0 &-1 \end{pmatrix}. $$

If we have a two-qubit Hamiltonian given as an explicit $4 \times 4$ matrix, it is very easy to calculate the Pauli-matrix decomposition,

$$ H = \sum_{i,j=1,x,y,z} a_{i,j} \left( \sigma_i \otimes \sigma_j \right), \quad a_{i,j} = \frac{1}{4} \trace\left[\left( \sigma_i \otimes \sigma_j \right) H \right] $$

The factor $\frac{1}{4}$ is due to the fact that the Pauli-matrices are not normalized: $\lVert\sigma_i\rVert = \sqrt{\trace\left[ \sigma_i^\dagger \sigma_i \right]} = \sqrt{2}$.

This can easily be implemented in just a few lines of Python:

import numpy as np

def HS(M1, M2):
    """Hilbert-Schmidt-Product of two matrices M1, M2"""
    return (np.dot(M1.conjugate().transpose(), M2)).trace()

def c2s(c):
    """Return a string representation of a complex number c"""
    if c == 0.0:
        return "0"
    if c.imag == 0:
        return "%g" % c.real
    elif c.real == 0:
        return "%gj" % c.imag
    else:
        return "%g+%gj" % (c.real, c.imag)

def decompose(H):
    """Decompose Hermitian 4x4 matrix H into Pauli matrices"""
    from numpy import kron
    sx = np.array([[0, 1],  [ 1, 0]], dtype=np.complex128)
    sy = np.array([[0, -1j],[1j, 0]], dtype=np.complex128)
    sz = np.array([[1, 0],  [0, -1]], dtype=np.complex128)
    id = np.array([[1, 0],  [ 0, 1]], dtype=np.complex128)
    S = [id, sx, sy, sz]
    labels = ['I', 'sigma_x', 'sigma_y', 'sigma_z']
    for i in xrange(4):
        for j in xrange(4):
            label = labels[i] + ' \otimes ' + labels[j]
            a_ij = 0.25 * HS(kron(S[i], S[j]), H)
            if a_ij != 0.0:
                print "%s\t*\t( %s )" % (c2s(a_ij), label)

For example, if we wanted to know the decomposition of the matrix $\diag(0,0,0,1)$,

H = np.array(np.diag([0,0,0,1]), dtype=np.complex128)
decompose(H)

we would find

0.25    *       ( I \otimes I )
-0.25   *       ( I \otimes sigma_z )
-0.25   *       ( sigma_z \otimes I )
0.25    *       ( sigma_z \otimes sigma_z )