将渐变样式应用于多个子集中的 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)
我想在 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)