【问题标题】:Conditional formatting of pandas DataFrame columns based on column header string基于列标题字符串的 pandas DataFrame 列的条件格式
【发布时间】:2018-12-19 09:40:48
【问题描述】:

如果单元格大于取决于列标题的值,我想突出显示它们。

我想“读取”列标题,如果它在字典 (CEPA_FW) 中,则返回相应的值。然后,如果该列中的任何单元格大于此值,则将它们填充为深橙色。我的努力低于,但我收到错误(ValueError:长度不匹配:预期轴有 1 个元素,新值有 4 个元素)。

df=pd.DataFrame(({'As':['0.001', 0, '0.001','0.06'], 'Zn': ['6','4','6','8'], 'Pb': ['0.006','0','0.005','0.005'], 'Yt': [1,0,0.002,6]}))
cols=df.columns

CEPA_FW=  {'Ag':0.05,'As' :0.05 ,'Ba':1.0,'B':1.0,'Cd' :0.01 ,'Cr' :0.05 ,'Co':0.001,'Cu' :1.0 ,'K':5.0,'Pb' :0.005 ,'Hg' :0.0002 ,'Mn':0.5,'Ni' :1.0 ,'Se':0.01,'Sn':0.5,'SO4':400.0,'Zn' :5.0}



def fill_exceedances(val):
    for header in cols:
        if header in CEPA_FW:
            for c in df[header]:
                fill = 'darkorange' if c> CEPA_FW[header] else ''
                return ['backgroundcolor: %s' % fill]

df.style.apply(fill_exceedances, axis = 1).to_excel('styled.xlsx', engine='openpyxl')

【问题讨论】:

  • appropriate limit is returned这是什么意思?
  • @RahulAgarwal,我已经编辑得更清楚了。

标签: python pandas conditional-formatting


【解决方案1】:

使用自定义函数创建DataFrame,按条件填充样式:

def fill_exceedances(x):
    color = 'orange'
    #get columns which are in keys of dict
    c = x.columns.intersection(CEPA_FW.keys())
    #filter columns and rename by dict
    df2 = x[c].rename(columns=CEPA_FW)
    #create boolean mask only for matched columns and compare
    mask = df2.astype(float).values > df2.columns[None,:].values
    #new DataFrame filled by no color
    df1 = pd.DataFrame('', index=x.index, columns=c)
    #set color by mask and add missing non matched columns names by reindex
    df1 = (df1.where(mask, 'background-color: {}'.format(color))
              .reindex(columns=x.columns, fill_value=''))

    return df1

df.style.apply(fill_exceedances, axis=None).to_excel('styled.xlsx', engine='openpyxl')

【讨论】:

  • 谢谢,当我将 ' >' 替换为 '
  • @flashliquid - 是的,也许还有更好的解决方案,但使用DataFrame 常用方式确实有优势。如果一些复杂的解决方案尤其好。
  • 我偶然发现了你不久前对类似问题给出的答案:stackoverflow.com/a/44942410/6108107 这种方法也适用于我的情况吗?功能是什么?
  • @flashliquid - 是的,可以将 mask = df2.astype(float).values > df2.columns[None,:].values 更改为 mask = (df2.astype(float).apply(lambda x: x > x.name, axis=0).values),但在大型 DataFrame 中性能更差
  • @flashliquid - 您可以将掩码更改为mask = df2.apply(pd.to_numeric, errors='coerce').fillna(np.inf).values > df2.columns[None,:].values
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多