def compare_matrices(matrix1, matrix2, threshold=0.05):
    """
    Compare 2 matrices nxm and return a matrix nxm with comparison data and
    stats. When the first columns match, they are considered as header and
    included in the results intact.

    :param matrix1: Reference Matrix of floats; first column could be header.
    :param matrix2: Matrix that will be compared; first column could be header
    :param threshold: Any difference greater than this percent threshold will
                      be reported.
    :return: Matrix with the difference in comparison, number of improvements,
             number of regressions, total number of comparisons.
    """
    improvements = 0
    regressions = 0
    same = 0
    new_matrix = []
    for line1, line2 in zip(matrix1, matrix2):
        new_line = []
        elements = zip(line1, line2)
        try:
            element1, element2 = next(elements)
        except StopIteration:
            new_matrix.append(new_line)
            continue
        if element1 == element2:
            new_line.append(element1)
            try:
                element1, element2 = next(elements)
            except StopIteration:
                new_matrix.append(new_line)
                continue
        while True:
            try:
                ratio = float(element2) / float(element1)
            except ZeroDivisionError:
                if float(element2) == 0:
                    new_line.append('.')
                    same += 1
                else:
                    new_line.append('error_%s/%s' % (element2, element1))
                    improvements += 1
                try:
                    element1, element2 = next(elements)
                except StopIteration:
                    break
                continue
            if ratio < 1 - threshold:
                regressions += 1
                new_line.append(100 * ratio - 100)
            elif ratio > 1 + threshold:
                improvements += 1
                new_line.append('+%.6g' % (100 * ratio - 100))
            else:
                same += 1
                new_line.append('.')
            try:
                element1, element2 = next(elements)
            except StopIteration:
                break
        new_matrix.append(new_line)
    total = improvements + regressions + same
    return new_matrix, improvements, regressions, total
