2016-11-29 91 views
1

通过使用Pandas Style,我试图突出显示那些从数据框中进行子集划分(行列和列划分)的单元格(如下所示)用条件格式:ValueError :(使用“熊猫风格”时的'系列长度必须与比较匹配'

enter image description here

例如,从0行1和列“亚当”和“吉尔”子集划分的单元格后,我想强调这些细胞绿色,如果它们的值大于他们相应的目标值,如果更低,则为橙色。

但是我保持谨慎摹运行代码时出现以下错误:

ValueError: ('Series lengths must match to compare', u'occurred at index 0'

我能做些什么来解决这个问题?

这是我的代码:

import pandas as pd 

def AboveTarget(s): # For dataframe style 
    green = s > df["Target"] 
    orange = s < df["Target"] 
    return ["background-color: #86f922" if v else "background-color: #faebde" if w else "background-color: white" for v, w in zip(green, orange)] 

df = pd.DataFrame({"Adam": [99.1, 95.2, 83.1], 
        "Gill": [99.2, 96.1, 81], 
        "Louis": [60, 71.5, 99.1], 
        "Target": [99, 98, 95] 
        }) 

html = (df.style.\ 
     apply(AboveTarget, subset = pd.IndexSlice[0:1, ["Adam", "Gill"]], axis = 1) 
     ) 

html 

回答

1

通过使用subset您正在传递切片元素到fu AboveTarget。结合axis=1,自变量sAboveTarget将是来自DataFrame的行,即具有索引["Adam","Gill"]的Pandas系列。您无法将其与df["Target"]比较,这是索引为[0,1,2]的系列。

您需要:

import pandas as pd 

def AboveTarget(s): # For dataframe style 
    green = s > s["Target"] 
    orange = s < s["Target"] 
    return ["background-color: #86f922" if v else "background-color: #faebde"\ 
     if w else "background-color: white" for v, w in zip(green, orange)] 

df = pd.DataFrame({"Adam": [99.1, 95.2, 83.1], 
       "Gill": [99.2, 96.1, 81], 
       "Louis": [60, 71.5, 99.1], 
       "Target": [99, 98, 95] 
       }) 

html = (df.style.\ 
     apply(AboveTarget, subset = pd.IndexSlice[0:1, ["Adam", "Gill", "Target"]], axis = 1) 
     ) 

html 

传柱“目标”的功能,并与相应的s["Target"]值进行比较。

1

在AboveTarget,您要比较一个pd.Seriess - 恰巧也有更少的元素... - 一个数据帧df,这就是为什么它不没有工作。

一种方法是做到以下几点:

def AboveTarget(s, df): # For dataframe style 
    green = s > df.loc[s.name, "Target"] 
    orange = s < df.loc[s.name, "Target"] 
    return ["background-color: #86f922" if v 
      else "background-color: #faebde" if w 
      else "background-color: white" 
      for v, w in zip(green, orange)] 

html = (df.style.\ 
     apply(AboveTarget, subset = pd.IndexSlice[0:1, ["Adam", "Gill", "Louis"]], 
       axis=1, args=(df,)) 
     ) 

html 

enter image description here

我传递df作为参数。


的另一种方式,我更喜欢,因为它不需要这么复杂的IndexSlice并且不需要经过df作为一个额外的参数如下:

def AboveTarget(s): 
    green = s > s['Target'] 
    orange = s < s['Target'] 
    return ["background-color: #86f922" if v 
      else "background-color: #faebde" if w 
      else "background-color: white" 
      for v, w in zip(green, orange)] 

html = (df.style.\ 
     apply(AboveTarget, subset = pd.IndexSlice[0:1], axis=1) 
     ) 

html 

它的工作原理,因为Target不是> Target< Target所以它会得到一个背景颜色white

相关问题