Compute conditional median of PANDAS dataframe
So, you want to get the medians of the groups by removing each value from the group in turn:

        group  =&gt;  individual removal of values

          NaN      [  ]   NaN   NaN   NaN
         25.0  =&gt;  25.0  [  ]  25.0  25.0
         15.0      15.0  15.0  [  ]  15.0
         19.0      19.0  19.0  19.0  [  ]

median   19.0      19.0  17.0  22.0  20.0


An other way of doing, beside manually reconstructing the group without the current value for each value, is to build the above intermediate matrix and ask for the median on each column. This will return a Series of length the length of the group, which is supported by SeriesGroupBy.transform.

The steps to get the desired result are:


build the matrix by repeating the input group as many time as its length;
fill the diagonal of the matrix with NaNs;
ask for the median by row/column depending on how you built the matrix.


The function that can be fed to transform may look like:

def median_without_element(group):
    matrix = pd.DataFrame([group] * len(group))
    np.fill_diagonal(matrix.values, np.NaN)
    return matrix.median(axis=1)




An other advantage of this approach is that you are able to reuse the same groups of elements and so cut on the need to recompute them again and again:

import numpy as np
import pandas as pd


def median_without_element(group):
    matrix = pd.DataFrame([group] * len(group))
    np.fill_diagonal(matrix.values, np.NaN)
    return matrix.median(axis=1)


def compute_medians(dataframe, groups_column='Time', values_column='A'):
    groups = dataframe.groupby(groups_column)[values_column]
    dataframe['Feature_1'] = groups.transform(np.median)
    dataframe['Feature_2'] = groups.transform(median_without_element)


if __name__ == '__main__':
    df = pd.DataFrame({
            'Time': [0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 0.0, 2.0, 0.0, 1.0, 2.0],
            'Id': [1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4],
            'A': [10, 15, np.NaN, 11, 16, 25, 10, 15, 9, 14, 19],
    })
    compute_medians(df)
    print(df)