Выделите максимум / мин на MultiIndex DataFrame - Панды - PullRequest
2 голосов
/ 15 апреля 2019

Предположим, что у вас есть 2-слойный массив данных MultiIndex:

df = pd.DataFrame([['one', 'A', 100,3], ['two', 'A', 101, 4], 
                   ['three', 'A', 102, 6], ['one', 'B', 103, 6], 
                   ['two', 'B', 104, 0], ['three', 'B', 105, 3]],
   columns=['c1', 'c2', 'c3', 'c4']).set_index(['c1', 'c2']).sort_index()
print(df)

, который выглядит следующим образом

           c3  c4
c1    c2         
one   A   100   3
      B   103   6
three A   102   6
      B   105   3
two   A   101   4
      B   104   0

Моя цель - выделить (со стилем Pandas) минимальный (или эквивалентно)максимум) между элементами 'c2' для всех столбцов 'c3' и 'c4' для каждого элемента в 'c1'

             c3      c4
c1    c2         
one   A   **100**   **3**
      B     103       6
three A   **102**     6
      B     105     **3**
two   A   **101**     4
      B     104     **0**

Есть ли у вас какие-либо предложения?

Я уже пробовал этот, но он работает по столбцам и не на основе индекса.

def highlight_min(data):

    attr = 'background-color: {}'.format(color)

    if data.ndim == 1:  # Series from .apply(axis=0) or axis=1
        is_max = data == data.min()
        return [attr if v else '' for v in is_max]
    else:  # from .apply(axis=None)
        is_max = data == data.min().min()
        return pd.DataFrame(np.where(is_max, attr, ''),
                            index=data.index, columns=data.columns)

df = df.style.apply(highlight_min, axis=0)

Результаты, если следующие

             c3      c4
c1    c2         
one   A   **100**     3
      B     103       6
three A     102       6
      B     105       3
two   A     101       4
      B     104     **0**

1 Ответ

2 голосов
/ 15 апреля 2019

Используйте GroupBy.transform с min и сравните по всем значениям:

def highlight_min(data):
    color= 'red'
    attr = 'background-color: {}'.format(color)

    if data.ndim == 1:  # Series from .apply(axis=0) or axis=1
        is_min = data == data.min()
        return [attr if v else '' for v in is_min]
    else: 
        is_min = data.groupby(level=0).transform('min') == data
        return pd.DataFrame(np.where(is_min, attr, ''),
                            index=data.index, columns=data.columns)
...