def mean_std_polishing(A, nb_iterations=5):
    """
    Iterative z-score on rows and columns.

    Args:
        A (pandas.DataFrame or numpy.array): matrix
        nb_iterations (int): number of polishing iterations

    Returns:
        pandas.DataFrame or numpy.array: Polished matrix

    Examples:
        >>> import pandas as pd
        >>> import numpy as np
        >>> np.random.seed(0)
        >>> data = pd.DataFrame(np.random.randn(5, 5),
                            index=["c1", "c2", "c3", "c4", "c5"],
                            columns=["gene1", "gene2", "gene3", "gene4", "gene5"])
        >>> norm_data = mean_std_polishing(data)
        >>> norm_data
               gene1     gene2     gene3     gene4     gene5
        c1  0.336095 -1.618781  0.187436  1.109617 -0.014367
        c2 -0.321684  0.586608 -1.606905  0.484159  0.857821
        c3  0.139260  0.860934  0.976541 -1.395814 -0.580921
        c4  1.243263  0.421752 -0.585940  0.282319 -1.361394
        c5 -1.363323 -0.161066  0.826375 -0.421998  1.120013

    """
    epsilon = 1e-10
    for i in range(nb_iterations):
        A = A - A.mean(axis=0)
        A = A / (A.std(axis=0) + epsilon)
        A = (A.T - A.T.mean(axis=0)).T
        A = (A.T / (A.T.std(axis=0) + epsilon)).T
    return A
