pandas 如何识别列中的组和它们的外边框?

dffbzjpn  于 2023-10-14  发布在  其他
关注(0)|答案(1)|浏览(137)

我的输入是这个简单的框架:

df = pd.DataFrame({'class': ['class_a', 'class_a', 'class_a', 'class_b', 'class_c', 'class_c'],
 'name': ['name_1', 'name_2', 'name_3', 'name_1', 'name_1', 'name_2'],
 'id': [5, 7, 1, 2, 3, 8]})
print(df)

     class    name  id
0  class_a  name_1   5
1  class_a  name_2   7
2  class_a  name_3   1
3  class_b  name_1   2
4  class_c  name_1   3
5  class_c  name_2   8

我想在列class中的每个组周围绘制一个蓝色实心边框(蓝色矩形)。
我在stackoverflow Pandas Style: Draw borders over whole row including the multiindex中找到了解决方案

s = df.style
for idx, group_df in df.groupby('class'):
    s = s.set_table_styles({group_df.index[0]: [{'selector': '', 'props': 'border-top: 3px solid blue;'}]}, 
                       overwrite=False, axis=1)

但有两个问题:
1.外部边界缺失
1.保存到Excel时,样式丢失

有没有一个变化,伙计们,我们可以修复至少“点1”?

vngu2lb8

vngu2lb81#

要在类列中的每个组周围绘制一个蓝色矩形,您需要设置分组行的顶部、底部、左侧和右侧边框。这需要设置每个组的第一行和最后一行的边框,以及整个组的边框。这可以像下面这样实现

import pandas as pd

# Sample data
df = pd.DataFrame({
    'class': ['class_a', 'class_a', 'class_a', 'class_b', 'class_c', 'class_c'],
    'name': ['name_1', 'name_2', 'name_3', 'name_1', 'name_1', 'name_2'],
    'id': [5, 7, 1, 2, 3, 8]
})

def style_border_around_class_groups(df):
    # Get the start and end indices of each group
    start_indices = df.groupby('class').head(1).index
    end_indices = df.groupby('class').tail(1).index

    # Define a dictionary to store styles for each cell
    styles_dict = {}

    # For each row in the dataframe
    for i, row in df.iterrows():
        # Default styles
        top_border = ""
        bottom_border = ""
        left_border = ""
        right_border = ""

        # If the row index is a start index, add top border
        if i in start_indices:
            top_border = "3px solid blue"
        # If the row index is an end index, add bottom border
        if i in end_indices:
            bottom_border = "3px solid blue"

        # Apply horizontal borders to all columns
        for col in df.columns:
            styles_dict[(i, col)] = f"border-top: {top_border}; border-bottom: {bottom_border};"

        # Apply left border only to the first column
        styles_dict[(i, df.columns[0])] += "border-left: 3px solid blue;"

        # Apply right border only to the last column
        styles_dict[(i, df.columns[-1])] += "border-right: 3px solid blue;"

    # Apply the styles
    s = df.style.apply(lambda x: [styles_dict.get((x.name, col), "") for col in df.columns], axis=1)
    return s

# Apply the styling function
styled_df = style_border_around_class_groups(df)
styled_df

这导致

相关问题