V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hackpro
V2EX  ›  Python

请教一个 Python pandas dataframe 特定列单元格内容高亮的问题

  •  
  •   hackpro · 2021-03-04 00:57:15 +08:00 · 1742 次点击
    这是一个创建于 1362 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 、pandas dataframe 带格式输出到 terminal/console 本身难度好像很大 遂转而输出到 html
    https://github.com/pandas-dev/pandas/issues/18066

    2 、html 表格高亮应该设置 df.stylebackground-color: yellow 属性
    https://pandas.pydata.org/pandas-docs/stable/user_guide/style.html

    3 、考虑到 dataframe 本身数据量很大,为了效率应该使用 df.apply 而非 df.applymap,后者是逐个元素处理
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html#pandas.DataFrame.apply

    折腾了快一个星期了,但是死活不起作用,求助各位大佬帮忙😢
    精简后的 python 代码如下:

    import pandas as pd
    import os
    import webbrowser
    
    def write_data_to_file(filename, content):
    
        file = open(filename, mode='w')
        file.write(content)
        file.close()
    
    
    def highlight_hot_color(col):
    
        hot_color = ['red', 'yellow', 'orange']
        check = [item in hot_color for item in col]
        return ['background-color: yellow' if v else '' for v in check]
    
    if __name__ == '__main__':
        df = pd.DataFrame([['Allen', 'red', 20], ['Tom', 'yellow', 30], ['Jack', 'blue', 40], ['Bob', 'grey', 50]], 
            columns=['name', 'color', 'age'])
        df.style.apply(highlight_hot_color, subset=['color'])
    
        html = df.to_html(index=False)
        file_name = 'test.html'
        path_name = os.path.abspath(file_name)
        url = 'file://' + path_name
        write_data_to_file(path_name, html)
        webbrowser.open(url)
    
    5 条回复    2021-03-05 17:13:04 +08:00
    ZAXON
        1
    ZAXON  
       2021-03-04 09:49:57 +08:00   ❤️ 1
    ```python
    df = pd.DataFrame([['Allen', 'red', 20], ['Tom', 'yellow', 30], ['Jack', 'blue', 40], ['Bob', 'grey', 50]],
    columns=['name', 'color', 'age'])
    df_result = df.style.apply(highlight_hot_color, subset=['color'])

    with open('test.html','w') as f:
    f.write(df_result.render())
    ```

    试试这样写?最后的生成 html 我是出于方便这么写的,你可以再看看有没有更好的写法。

    我更好奇的是第一个需求,是要达到 https://github.com/pandas-dev/pandas/issues/18066#issuecomment-371150717 这样的结果吗
    hackpro
        2
    hackpro  
    OP
       2021-03-04 12:18:00 +08:00
    @ZAXON 感谢大佬回复

    1 、高亮的问题部分解决了 但有一个问题
    df.style.apply 返回的是一个 Styler 类型 不再是 dataframe
    如果我需要给 dataframe 用上 pretty_html_table.build_table 进行表格风格挑战的话还是很麻烦

    2 、您提到的第一个问题 我是想做成链接里面的那样 但是好像难度很大
    目前输出到命令行我用的就是最原始的 print(df.to_string()) 😄
    ZAXON
        3
    ZAXON  
       2021-03-04 14:25:47 +08:00   ❤️ 2
    个人感觉 dataframe -> html.table 最灵活的方法还是直接使用 jinja2,我在公司邮件里面生成表格就是这样操作的。

    terminal 的格式化输出我推荐用的 https://github.com/willmcgugan/rich 这个库,不过不确定能不能解决你的这个问题。
    TimePPT
        4
    TimePPT  
       2021-03-04 14:31:25 +08:00
    @ZAXON jinja2+1,如果长期有样式需求,最好业务和样式分开处理。
    hackpro
        5
    hackpro  
    OP
       2021-03-05 17:13:04 +08:00
    @ZAXON @TimePPT 感谢两位老哥的建议和解答

    我现在的解决办法是用 dataframe.style 解决表格输出时高亮的问题,但是默认的表格实在是太丑了
    所以找了个 pretty_html_table 的包,可以非常方便的解决表格样式的问题
    from pretty_html_table import build_table
    html = build_table(data_frame, 'green_light')
    write_data_to_file('test.html', html)

    但是 pretty_html_table.build_table()接受 dataframe 作为参数,输出的是 str
    而我们之前讨论的 style.apply()接受 dataframe 作为参数,输出的是 pandas.io.formats.style.Styler
    两者不兼容 有什么办法把这两个结合在一起吗😭
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4623 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 05:34 · PVG 13:34 · LAX 21:34 · JFK 00:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.