【问题标题】:How to use lambda to apply style to Pandas DataFrame如何使用 lambda 将样式应用于 Pandas DataFrame
【发布时间】:2019-01-02 10:25:00
【问题描述】:

我有一个数据框,我想用红色突出显示出现“BBC”一词的单元格。

查看this SO threadthis one 我尝试了以下方法:

df.style.apply(lambda x: ["background-color: red" if x == "BBC News" else "background-color: green"])

df.style.apply(lambda x: ["background-color: red" if v == "BBC News" else "background-color: green" for v in x], axis=None)

但这不会给任何东西上色。 FWIW,我不知道我使用的示例中的xv 是什么。我假设x 是一个单元格,而v 将是单元格的一部分?

如何有条件地格式化单元格?我还会添加其他内容,即如果“CNN”出现在单元格中,颜色为黄色等。

编辑:我只是尝试了df.style.apply(lambda x: ["background-color: green"]),但什么也没发生(如果我使用#ff0000rgb(0,0,255),也是一样)。

明确地说,我在做:

df.style.apply(lambda x: ["background-color: #ff0000" if v['newsSource'] == "BBC News" else "background-color: #ffff00"], axis=None)
df.to_html("styletest.html")

所以我希望 HTML 文档 中的颜色可见,而不是数据框本身。

【问题讨论】:

  • 你可以试试颜色代码而不是字符串
  • @NerdicSapo - 你的意思是十六进制,即#FFFFF?我尝试用#ff0000 替换red 和用#ffff00 替换green(只是为了测试它是否有效),但没有显示颜色。
  • 您要更改检查第一列,即“新闻来源”。您需要访问列。
  • @rahlf23 - 去哪儿了,lamba x['newsSource']?我尝试将其添加到 [...if x['newsSource'] == "BBC News"...]` 但没有任何改变。说明虽然我通常很擅长理解列表推导,但我完全不知道第二个示例中的 xv 是什么,因此澄清这可能有助于我的理解。编辑:刚刚看到您编辑的评论。一秒钟让我申请。
  • @BruceWayne x 是每一列/行,而 v 是其中的每个元素?您是否也在寻找 v == "BBC News" 只是为了 "BBC" in v

标签: python python-3.x pandas


【解决方案1】:

好的,应该这样做:

import pandas as pd

df = pd.DataFrame([['BBC News','something','Test1'],
                    ['The Wall Street Journal','something else','Test2'],
                    ['BBC News','something else entirely','Test3']],
                    columns=['newsSource','description','title'])

html = df.style.apply(lambda x: ["background: red" if 'BBC' in x['newsSource'] and idx==0 else "" for idx, v in enumerate(x)], axis = 1).set_table_attributes('border="1" class="dataframe table table-hover table-bordered"').render()

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

解释:

lambda 运算符允许您对df 的每一行(由axis=1 指定)使用apply 以下["background: red" if 'BBC' in x['newsSource'] and idx==0 else "" for idx, v in enumerate(x)],其中xdf 的每一行。

在英语中,这意味着如果字符串'BBC' 包含在x['newsSource'] 中,则更改为"background: red",即dfx 行的'newsSource' 列。指定idx==0 的额外逻辑仅表示该行的第一个单元格x,为此我们必须enumerate(x) 才能跟踪当前列索引idx。否则,不要更改背景颜色,使用else ""。希望这很清楚!

【讨论】:

  • 是的,这行得通。 B 列和 C 列以红色突出显示。现在,我们需要将该逻辑应用于文本而不是数字:D
  • Hayoooo - 整排高亮红色!我们正在到达某个地方!现在,我怎样才能让这个单词显示为红色的单元格?
  • @AsheKetchum - 你是什么意思?是的,我指的是HTML。您能否以某种方式为 dataframe 本身着色,这在执行to_html() 时可能不会反映出来??
  • @BruceWayne 是的,就像你只是说 df.style.apply(highlight, axis=1) 一样,它会以所需的颜色打印 DataFrame,至少在交互式环境中
  • 非常感谢您的帮助! (灰太!)
【解决方案2】:

让我知道这样的方法是否有效?

def highlight_txt(s, txt):

    has_bbc = s.apply(lambda x: '')
    bbc = s.index.tolist().index('newsSource')
    has_bbc[bbc] = 'background-color: yellow' if txt in s[bbc] else 'background-color: green'

    return has_bbc

df.style.apply(lambda x: highlight_txt(x, 'BBC', axis=1))

【讨论】:

  • 什么也没发生 :( 仅供参考,如果我在 .apply 行之前调用 type(df),我确实会得到 <class 'pandas.core.frame.DataFrame'> 编辑:编辑后仍然没有任何事情
  • k 再试一次?我忘了把if 'a' in s[bbc]改成if 'BBC' in s[bbc]
  • 还是什么都没有 :(
  • 我觉得逻辑现在应该是 xD,它适用于我的简单 df df = pd.DataFrame(columns=['a','b','c'], data=[['b', 'a', 'd'], ['c', 'x', 'f'], ['b', 's', 'w']])
  • 这对我来说并没有突出任何东西。 Screenshot of my code(抱歉是截图,不知道有什么更好的代码展示方式)
【解决方案3】:

为了清楚起见,我会将其分离为一个函数,然后遍历行:

def highlight_cell(row):
    background = []
    for cell in row:
        color = 'background-color: green'
        if 'BBC' in cell:
            color = 'background-color: red'
        elif 'CNN' in cell:
            color = 'background-color: yellow'
        background.append(color)
    return background

df.style.apply(highlight_cell, axis=1)

【讨论】:

  • 什么都没有发生,没有着色 :(
猜你喜欢
  • 2019-12-25
  • 1970-01-01
  • 2020-03-12
  • 2018-11-23
  • 1970-01-01
  • 2018-11-21
  • 2019-10-13
  • 2019-04-10
  • 1970-01-01
相关资源
最近更新 更多