将渐变样式应用于多个子集中的 pandas DataFrame

Applying gradient styling to pandas DataFrame in multiple subsets

我想在 pandas 数据框的多个小节中应用颜色渐变(从绿色到黄色再到红色:基于值)。在每个小节中,值都将介于 0 和 1 之间。

到目前为止,我拥有的是:

def applyMetricGradient(df, idx_pairs, low=0, high=0):

    def background_gradient(s, m, M, cmap='RdYlGn', low=0, high=0):
        rng = M - m
        norm = colors.Normalize(m - (rng * low),
                                M + (rng * high))
        normed = norm(s.values)
        c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
        return ['background-color: %s' % color for color in c]

    for eachPair in idx_pairs:
        start = eachPair[0]
        end = eachPair[1]

        display(df.loc[df.index[start:end]]['Values'].values.max().max())
        df = df.style.apply(background_gradient,
                            cmap='RdYlGn',
                            m=df.loc[df.index[start:end]]['Values'].values.min().min(),
                            M=df.loc[df.index[start:end]]['Values'].values.max().max(),
                            low=0,
                            high=0.2,
                            subset = df.index[start:end], axis=0)
        display(df)

applyMetricGradient(corrStat.set_index('Metrics'), [(0,3), (8,13)])

我收到这个错误:

KeyError: "None of [Index(['a', 'b', 'c'], dtype='object', name='Metrics')] are in the [columns]"

编辑

我能够通过使用 pd.IndexSlice[],

在一个子集上设置渐变
def applyMetricGradient(df, idx_pairs, low=0, high=0):

    def background_gradient(s, m, M, cmap='RdYlGn', low=0, high=0):
        rng = M - m
        norm = colors.Normalize(m - (rng * low),
                                M + (rng * high))
        normed = norm(s.values)
        c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
        return ['background-color: %s' % color for color in c]

    for eachPair in idx_pairs:
        start = eachPair[0]
        end = eachPair[1]

        display(df.loc[df.index[start:end]]['Values'].values.max().max())
        df = df.style.apply(background_gradient,
                            cmap='RdYlGn',
                            m=df.loc[df.index[start:end]]['Values'].values.min().min(),
                            M=df.loc[df.index[start:end]]['Values'].values.max().max(),
                            low=0,
                            high=0.2,
                            subset = pd.IndexSlice[df.index[start:end], 'Values'], axis=1)
        display(df)

applyMetricGradient(corrStat.set_index('Metrics'), [(0,3), (8,13)])

但是对于下一个子集,我得到

AttributeError: 'Styler' object has no attribute 'loc'

有什么解决方法吗??

最后我能够通过这个来完成这项工作:

def applyMetricGradient(df, idx_pairs, low=0, high=0):

    def background_gradient(s, m, M, cmap='RdYlGn', low=0, high=0):
        rng = M - m
        norm = colors.Normalize(m - (rng * low),
                                M + (rng * high))
        normed = norm(s.values)
        c = [colors.rgb2hex(x) for x in plt.cm.get_cmap(cmap)(normed)]
        return ['background-color: %s' % color for color in c]

    for idx, pairs in enumerate(idx_pairs):
        start = pairs[0]
        end = pairs[1]
        _min = pairs[2]
        _max = pairs[3]
        if idx == 0: 
            df = df.style.apply(background_gradient,
                                cmap='RdYlGn',
                                m=_min,
                                M=_max,
                                low=0,
                                high=0.2,
                                subset = pd.IndexSlice[df.index[start:end], 'Values'], axis=1)

        else :
            df = df.apply(background_gradient,
                                cmap='RdYlGn',
                                m=_min,
                                M=_max,
                                low=0,
                                high=0.2,
                                subset = pd.IndexSlice[df.index[start:end], 'Values'], axis=1)
    return df
t = pd.DataFrame(columns = ['Values'], index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'])
t['Values'] = np.random.normal(size=14)
gradList = [(0,3, t.iloc[0:3].min(), t.iloc[0:3].max()),
            (6,9, t.iloc[6:9].min(), t.iloc[6:9].max())]

applyMetricGradient(t, gradList)