Python 将样式应用于数据帧的任意(非乘积)子集

Python 将样式应用于数据帧的任意(非乘积)子集,python,pandas,styles,Python,Pandas,Styles,如何将样式应用于数据帧的任意子集?具体地说,我有一个数据帧df,其中包含一些NaN,我想在任何地方对其应用背景渐变,除了存在NaN的地方(对所有单元格应用相同的颜色贴图) 我知道background\u gradient(以及更一般的applymap)有一个子集参数,但从文档中我不理解如何使用它来选择数据帧的任意子集 import numpy as np import pandas as pd df = pd.DataFrame(data={'A': [0, 1, np.nan], 'B':

如何将样式应用于数据帧的任意子集?具体地说,我有一个数据帧
df
,其中包含一些NaN,我想在任何地方对其应用背景渐变,除了存在NaN的地方(对所有单元格应用相同的颜色贴图)

我知道
background\u gradient
(以及更一般的
applymap
)有一个
子集
参数,但从文档中我不理解如何使用它来选择数据帧的任意子集

import numpy as np
import pandas as pd

df = pd.DataFrame(data={'A': [0, 1, np.nan], 'B': [.5, np.nan, 0], 'C': [np.nan, 1, 1]})
mask = ~pd.isnull(df)
那么如果我尝试

df.style.background_gradient(subset=mask)
我得到一个错误:

IndexingError: Too many indexers
我知道如何在特定情况下将样式应用于数据帧的子集,其中该子集是索引和列的笛卡尔乘积,使用类似于此处的解决方案:。所以问题是,当子集不是这样的产品时,该怎么办,如上面的例子所示


一种解决方案可能是通过列循环并逐列应用样式(然后每个应用程序都是笛卡尔积子集)。在我的例子中,我可以将
low
high
参数传递给
background\u gradient
方法,以强制颜色贴图在列之间匹配,但当(如上所述)其中一个或多个列包含唯一的非NaN值时,这将失败。反过来,重写
背景梯度
函数可以绕过此问题,但这显然是不可取的。

您可以为此编写自定义函数:

from matplotlib.cm import get_cmap
cmap = get_cmap('PuBu')

# update with low-high option
def threshold(x,low=0,high=1,mid=0.5):
    # nan cell
    if np.isnan(x): return ''

    # non-nan cell
    x = (x-low)/(high-low)
    background = f'background-color: rgba{cmap (x, bytes=True)}'
    text_color = f'color: white' if x > mid else ''
    return background+';'+text_color

# apply the style
df.style.applymap(threshold, low=-1, high=1, mid=0.3)
输出:


这似乎是一个开放的领域。@rpanai我同意,如果可以从样式函数中屏蔽NaN,那么在我的情况下就可以了。然而,在我看来,应该有某种方式将样式应用于数据帧的任意子集,无论这些子集是否由NaN定义。@rpanai:pandas在2019/v0.17.1年被合并为一个
高亮显示\u null
。我认为这个问题已经过时了。OP:你能重写一下,并说明熊猫的版本吗?恐怕我不知道我当时用的是什么版本的熊猫。但正如我在上面的评论中所说,我的问题比忽略渐变填充中的NAN更一般(尽管这是我当时想到的特定用例):它是关于将样式应用于数据帧的任意子集,可能由布尔掩码表示。据我所知,目前最好的方法是使用自定义函数与applymap结合使用,正如Quang Hoang的回答。谢谢@QuangHoang,效果很好。我觉得奇怪的是这样的东西不是内置的。