PANDAS-如何根据索引中的值为整行着色

时间:2019-04-06 13:29:13

标签: python excel pandas dataframe

我有以下MultiIndex Dataframe:

pt = df[df['Top Task Work Type'].isin(['Customer Billable','Customer Non-Billable', 'Work at risk'])].pivot_table(
    index = ['Resource id', 'End Customer Name', 'Top Task Work Type'],
    columns= ['Fiscal Quarter','Fiscal Week In Qtr Num Int'],
    values= ['Total Hours'],
    aggfunc = {'Total Hours' : np.sum}
)

如您在上面看到的,我使用“首要任务工作类型”作为过滤器从excel工作表创建数据透视表。它创建的数据透视表有40列。

Excel输出如下:

https://imgur.com/j6VLxTU

我想用红色(彩色)突出显示所有值“ Customer Non-Billable”的行,例如:

https://imgur.com/CSMispg

我试图通过多种方式将样式应用于dt:

def highlight_col(x):
    #copy df to new - original data are not changed
    df = x.copy()
    #set by condition
    mask = pt.index.get_level_values('Top Task Work Type') == 'Customer Non-Billable'
    df.loc[mask, :] = 'background-color: yellow'
    df.loc[~mask,:] = 'background-color: ""'
    return df    

pt.style.apply(highlight_col, axis=1)

没有成功。我已经能够为基于列的行设置某些值,但是我想为所有具有“ Customer Non-Billable”值的行上色

非常感谢您的帮助

2 个答案:

答案 0 :(得分:1)

这里使用Pandas> 0.20策略进行样式设置。

import pandas as pd
from pandas.compat import StringIO
import xlsxwriter
import xlwt
import openpyxl

csvdata = StringIO("""date,LASTA,LASTB,LASTC
1999-03-15,-2.5597,8.20145,16.900
1999-03-17,2.6375,8.12431,17.125
1999-03-18,2.6375,-8.27908,16.950
1999-03-19,2.6634,8.54914,17.325
1999-04-06,2.8537,7.63703,17.750""")

df = pd.read_csv(csvdata, sep=",", index_col="date", parse_dates=True, infer_datetime_format=True)

def color_negative_red(val):
    color = 'red' if val < 0 else 'white'
    return 'background-color: %s' % color            

df.style.\
    applymap(color_negative_red).\
    to_excel('styletest.xlsx', engine='openpyxl')

使用XlsxWriter策略进行样式设置。也许这样可以更轻松地访问要样式化的数据。

import pandas as pd
from pandas.compat import StringIO
import xlsxwriter
import xlwt
import openpyxl

csvdata = StringIO("""date,LASTA,LASTB,LASTC
1999-03-15,-2.5597,8.20145,16.900
1999-03-17,2.6375,8.12431,17.125
1999-03-18,2.6375,-8.27908,16.950
1999-03-19,2.6634,8.54914,17.325
1999-04-06,2.8537,7.63703,17.750""")

df = pd.read_csv(csvdata, sep=",", index_col="date", parse_dates=True, infer_datetime_format=True)

# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter("styletest.xlsx", engine='xlsxwriter')

# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')

# Get the xlsxwriter workbook and worksheet objects.
workbook  = writer.book
worksheet = writer.sheets['Sheet1']

# Add some cell formats.
format1 = workbook.add_format({'num_format': '#,##0.00'})
format2 = workbook.add_format({'num_format': '0%'})
format3 = workbook.add_format({'bg_color': 'yellow'})

# Set the column width and format.
worksheet.set_column('B:B', 18, format2)
worksheet.set_row(2, 5, format3)

# Set the format but not the column width.
worksheet.set_column('C:C', None, format2)

# Close the Pandas Excel writer and output the Excel file.
writer.save()

DataFrame跟踪Multiindex中的数据子集。

import pandas as pd
import numpy as np

midx = pd.MultiIndex.from_product([['A0','A1'], ['B0','B1','B2','B3']])
columns = ['foo', 'bar']
df = pd.DataFrame(np.arange(16).reshape((len(midx), len(columns))),index=midx, columns=columns)

def style(val):
    return 'background-color: yellow'

idx = pd.IndexSlice[:, 'B0':'B1']
print(df.loc[idx,:])

df.style.applymap(style, subset=idx).to_excel('styletest.xlsx', engine='openpyxl')

但是指定的IndexSlice无法正常工作。但这应该是模式。

答案 1 :(得分:0)

我使用XMLwriter使它工作

我首先创建了要使用的样式:

########## Format definition for CAP #########
format_cap = workbook.add_format({'bg_color': '#FFC7CE',
                               'font_color': '#9C0006'})

然后应用它:

worksheet_all.conditional_format('C5:BC500', {'type': 'formula',
                                         'criteria': '=LEFT($C5, 250)="Customer Non-Billable"', 
                                          'format': format_cap})

有效