def zscore_normalization(data, normalize='samples'):
    """
    This function normalizes each sample by using its mean and standard deviation (mean=0, std=1).

    :param data:
    :param str normalize: whether the normalization should be done by 'features' (columns) or 'samples' (rows)
    :return: Pandas dataframe.

    Example::
        data = pd.DataFrame({'a': [2,5,4,3,3], 'b':[4,4,6,5,3], 'c':[4,14,8,8,9]})
        result = zscore_normalization(data, normalize='samples')
        result
                  a         b         c
                0 -1.154701  0.577350  0.577350
                1 -0.484182 -0.665750  1.149932
                2 -1.000000  0.000000  1.000000
                3 -0.927173 -0.132453  1.059626
                4 -0.577350 -0.577350  1.154701
    """
    if normalize is None or normalize == 'samples':
        normData = data.sub(data.mean(axis=1), axis=0).div(data.std(axis=1), axis=0)

    else:
        normData = data.sub(data.mean(axis=0), axis=1).div(data.std(axis=0), axis=1)

    return normData