Source code for acore.normalization.strategies

"""Strategies for data normalization used by `normalize_data`."""

import pandas as pd
from sklearn import preprocessing


# ! update docstring: example is not correct
[docs] def median_zero_normalization(data, normalize="samples"): """ This function normalizes each sample by using its median. :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 = median_zero_normalization(data, normalize='samples') result a b c 0 -1.333333 0.666667 0.666667 1 -2.666667 -3.666667 6.333333 2 -2.000000 0.000000 2.000000 3 -2.333333 -0.333333 2.666667 4 -2.000000 -2.000000 4.000000 """ if normalize is None or normalize == "samples": norm_data = data.sub(data.median(axis=1), axis=0) else: norm_data = data.sub(data.median(axis=0), axis=1) return norm_data
# ! Update docstring: example is not correct
[docs] def median_normalization(data, normalize="samples"): """ This function normalizes each sample by using its median. :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 = median_normalization(data, normalize='samples') result a b c 0 -1.333333 0.666667 0.666667 1 -2.666667 -3.666667 6.333333 2 -2.000000 0.000000 2.000000 3 -2.333333 -0.333333 2.666667 4 -2.000000 -2.000000 4.000000 """ if normalize is None or normalize == "samples": norm_data = data.sub(data.median(axis=1) - data.median(axis=1).median(), axis=0) else: norm_data = data.sub(data.median(axis=0) - data.median(axis=0).median(), axis=1) return norm_data
[docs] 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": norm_data = data.sub(data.mean(axis=1), axis=0).div(data.std(axis=1), axis=0) else: norm_data = data.sub(data.mean(axis=0), axis=1).div(data.std(axis=0), axis=1) return norm_data
[docs] def median_polish_normalization(data, max_iter=250): """ This function iteratively normalizes each sample and each feature to its median until medians converge. :param data: :param int max_iter: number of maximum iterations to prevent infinite loop. :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 = median_polish_normalization(data, max_iter = 10) result a b c 0 2.0 4.0 7.0 1 5.0 7.0 10.0 2 4.0 6.0 9.0 3 3.0 5.0 8.0 4 3.0 5.0 8.0 """ mediandf = data.copy() for _ in range(max_iter): row_median = mediandf.median(axis=1) mediandf = mediandf.sub(row_median, axis=0) col_median = mediandf.median(axis=0) mediandf = mediandf.sub(col_median, axis=1) if (mediandf.median(axis=0) == 0).all() and ( mediandf.median(axis=1) == 0 ).all(): break norm_data = data - mediandf return norm_data
[docs] def quantile_normalization(data) -> pd.DataFrame: """ Applies quantile normalization to each column in pandas.DataFrame. :param data: pandas.DataFrame with features as columns and samples as 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 = quantile_normalization(data) result a b c 0 3.2 4.6 4.6 1 4.6 3.2 8.6 2 3.2 4.6 8.6 3 3.2 4.6 8.6 4 3.2 3.2 8.6 """ rank_mean = ( data.T.stack().groupby(data.T.rank(method="first").stack().astype(int)).mean() ) normdf = data.T.rank(method="min").stack().astype(int).map(rank_mean).unstack().T return normdf
# ToDo: check if fillna(0) is necessary for normalize. Imputation should be handled # separately.
[docs] def linear_normalization(data, method="l1", normalize="samples") -> pd.DataFrame: """ This function scales input data to a unit norm. For more information visit: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.normalize.html :param data: pandas.DataFrame with samples as rows and features as columns. :param str method: norm to use to normalize each non-zero sample or non-zero feature (depends on axis). :param str normalize: axis used to normalize the data along. If 'samples', independently normalize each sample, if 'features' normalize each feature. :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 = linear_normalization(data, method = "l1", normalize = 'samples') result a b c 0 0.117647 0.181818 0.093023 1 0.294118 0.181818 0.325581 2 0.235294 0.272727 0.186047 3 0.176471 0.227273 0.186047 4 0.176471 0.136364 0.209302 """ if normalize is None or normalize == "samples": normvalues = preprocessing.normalize( data.fillna(0).values, norm=method, axis=0, copy=True, return_norm=False ) else: normvalues = preprocessing.normalize( data.fillna(0).values, norm=method, axis=1, copy=True, return_norm=False ) normdf = pd.DataFrame(normvalues, index=data.index, columns=data.columns) return normdf
if __name__ == "__main__": data = pd.DataFrame( {"a": [2, 5, 4, 3, 3], "b": [4, 4, 6, 5, 3], "c": [4, 14, 8, 8, 9]} ) result = linear_normalization(data, method="l1", normalize="samples") print(result) data = pd.DataFrame( {"a": [2, 5, 4, 3, 3], "b": [4, 4, 6, 5, 3], "c": [4, 14, 8, 8, 9]} ) result = median_zero_normalization(data, normalize="samples") print(result)