代码之家  ›  专栏  ›  技术社区  ›  Jeff Tilton

Pandas根据另一个数据帧mith多索引设置元素样式

  •  1
  • Jeff Tilton  · 技术社区  · 6 年前

    我之前问过这个问题 Pandas set element style dependent on another dataframe ,我有一个可行的解决方案,但现在我正试图将其应用于具有多索引的数据帧,我得到了一个错误,我不理解。

    问题

    我有一个熊猫df和相应的布尔矩阵。我想根据布尔矩阵突出显示df。

    数据

    import pandas as pd
    import numpy as np
    from datetime import datetime
    
    date = pd.date_range(start = datetime(2016,1,1), end = datetime(2016,2,1), freq = "D")
    i = len(date)
    dic = {'X':pd.DataFrame(np.random.randn(i, 2),index = date, columns = ['A','B']),
           'Y':pd.DataFrame(np.random.randn(i, 2),index = date, columns = ['A','B']),
           'Z':pd.DataFrame(np.random.randn(i, 2),index = date, columns = ['A','B'])}
    df = pd.concat(dic.values(),axis=1,keys=dic.keys())
    
    
    boo =  [True, False]
    bool_matrix = {'X':pd.DataFrame(np.random.choice(boo, (i,2), p=[0.3,.7]), index = date, columns = ['A','B']),
                   'Y':pd.DataFrame(np.random.choice(boo, (i,2), p=[0.3,.7]), index = date, columns = ['A','B']),
               'Z':pd.DataFrame(np.random.choice(boo, (i,2), p=[0.3,.7]), index = date, columns = ['A','B'])}
    
    bool_matrix =pd.concat(bool_matrix.values(),axis=1,keys=bool_matrix.keys())
    

    我尝试的解决方案

    def highlight(value):
        return 'background-color: green' 
    my_style = df.style
    for column in df.columns:
        for i in df[column].index:
            data = bool_matrix.loc[i, column]
            if data: 
                my_style = df.style.use(my_style.export()).applymap(highlight, subset = pd.IndexSlice[i, column])
    
    my_style
    

    后果

    上面抛出了一个 AttributeError: 'Series' object has no attribute 'applymap'

    我不明白什么是作为一个系列的回报。这是我正在设置的单个值,此解决方案适用于非多索引df,如下所示。

    无多索引

    import pandas as pd
    import numpy as np
    from datetime import datetime
    np.random.seed(24)
    date = pd.date_range(start = datetime(2016,1,1), end = datetime(2016,2,1), freq = "D")
    df = pd.DataFrame({'A': np.linspace(1, 100, len(date))})
    df = pd.concat([df, pd.DataFrame(np.random.randn(len(date), 4), columns=list('BCDE'))],
                   axis=1)
    
    df['date'] = date
    df.set_index("date", inplace = True)
    
    boo =  [True, False]
    bool_matrix = pd.DataFrame(np.random.choice(boo, (len(date), 5),p=[0.3,.7]), index = date,columns=list('ABCDE'))
    
    def highlight(value):
        return 'background-color: green' 
    my_style = df.style
    for column in df.columns:
        for i in bool_matrix.index:
            data = bool_matrix.loc[i, column]
            if data: 
                my_style = df.style.use(my_style.export()).applymap(highlight, subset = pd.IndexSlice[i,column])
    my_style
    

    文档

    这个 docs 参考CSS类并说“索引标签单元格包括level,其中k是多索引中的level。”很明显,我将这一错误编入索引,但我对如何继续进行感到困惑。

    1 回复  |  直到 3 年前
        1
  •  2
  •   gepcel    6 年前

    有一个可运行的示例非常好。

    您可以使用 df.style.apply(..., axis=None) 将突出显示方法应用于整个数据帧。

    与您的 df bool_matrix ,请尝试以下操作:

    def highlight(value):
        d = value.copy()
        for c in d.columns:
            for r in df.index:
                if bool_matrix.loc[r, c]:
                    d.loc[r, c] = 'background-color: green'
                else:
                    d.loc[r, c] = ''
        return d
    
    df.style.apply(highlight, axis=None)
    

    或者,为了简化代码,您可以尝试:

    def highlight(value):
        return bool_matrix.applymap(lambda x: 'background-color: green' if x else '')
    
    df.style.apply(highlight, axis=None)
    

    希望这是你需要的。