You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame逐行对比两列词列表并高亮差异实现方法

账户访问权限审计功能的权限列差异高亮实现方案

需求说明

基于Neo4j数据源开发账户间访问权限审计功能,需要逐行对比DataFrame中存储权限列表的两列单元格不对,哦,正常写:

需求背景

开发基于Neo4j数据源的账户间访问权限审计功能,需逐行对比DataFrame中存储权限列表的两列单元格内容,高亮展示同组两个用户的权限差异项。
示例数据结构如下:

ID| User A | ROLES | Rights | SOME INFO | USER B| ROLES | RIGHTS 
-----------------------------------------------------------------
1 | titi   | Reader|[a,b,d] | blalbalbla| toto  | writer|[c,d,f,a]
------------------------------------------------------------------
2 | tata   | Manage|[b,f,g] | blalblalba| tutu  | Reader|[a,b,d]

对比规则为逐行匹配同组用户权限:第一行比对titi和toto的权限、第二行比对tata和tutu的权限,将两边不一致的权限项做高亮标记。

现有代码

当前已完成基础表格渲染逻辑,代码如下:

def _render_results(self, queries):
    num_queries = len(queries)
    # For each selected query
    for counter, q in enumerate(queries, 1):
        # Print result
        if q['result']:
            df = pandas.DataFrame(q['result'])
            # Replace header
            df = df[1:]
            df.columns = q['headers']
            # Table settings
            pandas.set_option('display.max_rows', 500000)
            pandas.set_option('display.max_colwidth', 0)
            display(df)  
        else:
            self.printmd("No Results !")

当前仅通过display函数直接输出原生表格,未实现差异对比和高亮逻辑,以下是可直接落地的实现方案。

实现步骤

  • 第一步:统一权限列格式
    先兼容权限列的两种存储格式:如果是[a,b,d]形式的字符串就解析为列表,如果是原生Python列表就直接使用,避免格式问题导致对比出错。
  • 第二步:逐行计算权限差集
    逐行遍历两个权限列,通过集合运算分别算出A用户独有、B用户独有的权限项,给差异项包裹带背景色的HTML标签,共有权限保持普通文本。
  • 第三步:渲染带样式的表格
    替换原有直接输出原生DataFrame的逻辑,使用pandas Styler渲染表格,关闭HTML转义保证高亮标签生效。

改造后可直接复用的代码

import pandas as pd

def _highlight_diff_permissions(row, col_a, col_b):
    # 解析权限值为集合,兼容字符串列表、原生列表两种格式
    def _parse_perm(val):
        if isinstance(val, str):
            val = val.strip('[]').split(',')
            val = [v.strip() for v in val if v.strip()]
        return set(val) if val else set()
    
    perm_a = _parse_perm(row[col_a])
    perm_b = _parse_perm(row[col_b])
    # 计算两边独有的权限
    a_only = perm_a - perm_b
    b_only = perm_b - perm_a

    # 生成A列带高亮标签的内容
    a_rendered = []
    for p in perm_a:
        if p in a_only:
            # 红色标记A独有权限
            a_rendered.append(f'<span style="background-color: #ff6b6b; color: #fff; padding: 1px 3px; border-radius: 3px;">{p}</span>')
        else:
            a_rendered.append(p)
    # 生成B列带高亮标签的内容
    b_rendered = []
    for p in perm_b:
        if p in b_only:
            # 蓝色标记B独有权限
            b_rendered.append(f'<span style="background-color: #4dabf7; color: #fff; padding: 1px 3px; border-radius: 3px;">{p}</span>')
        else:
            b_rendered.append(p)
    
    row_res = row.copy()
    row_res[col_a] = '[' + ','.join(a_rendered) + ']'
    row_res[col_b] = '[' + ','.join(b_rendered) + ']'
    return row_res

def _render_results(self, queries):
    # 配置需要对比的两个权限列名,和实际表头保持一致即可
    PERM_COL_A = "Rights"
    PERM_COL_B = "RIGHTS"
    
    for counter, q in enumerate(queries, 1):
        if q['result']:
            df = pd.DataFrame(q['result'])
            df = df[1:]
            df.columns = q['headers']
            pd.set_option('display.max_rows', 500000)
            pd.set_option('display.max_colwidth', 0)
            
            # 逐行处理权限列,添加高亮标签
            df = df.apply(lambda x: _highlight_diff_permissions(x, PERM_COL_A, PERM_COL_B), axis=1)
            # 渲染带HTML样式的表格,关闭转义保证标签生效
            styler = df.style.hide(axis='index').format(escape=False).set_table_styles([
                {'selector': 'td', 'props': 'padding: 8px; font-size: 14px; text-align: left;'}
            ])
            display(styler)  
        else:
            self.printmd("No Results !")

效果说明

  • 红色高亮为A用户持有、B用户未持有的权限
  • 蓝色高亮为B用户持有、A用户未持有的权限
  • 双方共有的权限保持普通文本样式无高亮
  • 可直接修改代码中background-color的色值调整高亮配色。

内容的提问来源于stack exchange,提问作者MathRig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:45:35