Pandas 样式:在包括多索引在内的整行上绘制边框
Pandas Style: Draw borders over whole row including the multiindex
我在 jupyter 笔记本中使用 pandas 样式来强调此数据框中子组之间的边界:
(从技术上讲:在每一个变化的多索引处绘制边界,但忽略最低级别)
# some sample df with multiindex
res = np.repeat(["response1","response2","response3","response4"], 4)
mod = ["model1", "model2","model3","model4"]*len(res)
data = np.random.randint(0,50,size=len(mod))
df = pd.DataFrame(zip(res,mod,data), columns=["res","mod","data"])
df.set_index(["res","mod"], inplace=True)
# set borders at individual frequency
indices_with_borders = range(0,len(df), len(np.unique(mod)))
df.style.set_properties(subset=(df.index[indices_with_borders], df.columns), **{
'border-width': '1px', "border-top-style":"solid"})
结果:
现在看起来有点傻,边框只画在列上,而不是一直延伸到多索引。这将是一个更令人愉悦的风格:
有人知道如何/是否可以实现吗?
提前致谢!
s = df.style
for l0 in ['response1', 'response2', 'response3', 'response4']:
s.set_table_styles({(l0, 'model4'): [{'selector': '', 'props': 'border-bottom: 3px solid red;'}],
(l0, 'model1'): [{'selector': '.level0', 'props': 'border-bottom: 3px solid green'}]},
overwrite=False, axis=1)
s
因为多索引会稀疏和跨越行,所以您需要小心控制行 类。这有点痛苦,但它可以满足您的需求...
s = df.style
for idx, group_df in df.groupby('res'):
s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 3px solid green;'}]},
overwrite=False, axis=1)
s
我接受了 Attack68 的回答,并认为我会展示如何使其更通用,如果您在多索引中有更多级别,这将很有用。允许您按多索引中的任何级别进行分组,并在该级别的顶部添加边框。因此,如果我们想对关卡 mod 做同样的事情,我们也可以这样做:
df = df.sort_index(level=['mod'])
s = df.style
for idx, group_df in df.groupby('mod'):
s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 3px solid green;'}]},
overwrite=False, axis=1)
s
我在 jupyter 笔记本中使用 pandas 样式来强调此数据框中子组之间的边界:
(从技术上讲:在每一个变化的多索引处绘制边界,但忽略最低级别)
# some sample df with multiindex
res = np.repeat(["response1","response2","response3","response4"], 4)
mod = ["model1", "model2","model3","model4"]*len(res)
data = np.random.randint(0,50,size=len(mod))
df = pd.DataFrame(zip(res,mod,data), columns=["res","mod","data"])
df.set_index(["res","mod"], inplace=True)
# set borders at individual frequency
indices_with_borders = range(0,len(df), len(np.unique(mod)))
df.style.set_properties(subset=(df.index[indices_with_borders], df.columns), **{
'border-width': '1px', "border-top-style":"solid"})
结果:
现在看起来有点傻,边框只画在列上,而不是一直延伸到多索引。这将是一个更令人愉悦的风格:
有人知道如何/是否可以实现吗? 提前致谢!
s = df.style
for l0 in ['response1', 'response2', 'response3', 'response4']:
s.set_table_styles({(l0, 'model4'): [{'selector': '', 'props': 'border-bottom: 3px solid red;'}],
(l0, 'model1'): [{'selector': '.level0', 'props': 'border-bottom: 3px solid green'}]},
overwrite=False, axis=1)
s
因为多索引会稀疏和跨越行,所以您需要小心控制行 类。这有点痛苦,但它可以满足您的需求...
s = df.style
for idx, group_df in df.groupby('res'):
s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 3px solid green;'}]},
overwrite=False, axis=1)
s
我接受了 Attack68 的回答,并认为我会展示如何使其更通用,如果您在多索引中有更多级别,这将很有用。允许您按多索引中的任何级别进行分组,并在该级别的顶部添加边框。因此,如果我们想对关卡 mod 做同样的事情,我们也可以这样做:
df = df.sort_index(level=['mod'])
s = df.style
for idx, group_df in df.groupby('mod'):
s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 3px solid green;'}]},
overwrite=False, axis=1)
s