2017-05-24 6 views
2

Ich habe einen Pandas-Datenrahmen, der etwas wie unten gezeigt ist.Python - Verwenden von Pandas zum Formatieren von Excel-Zelle

dataframee

ich die Spalte "Pass/Fail" als if Fail --> red background, else green background zu formatieren möchten, wie:

format

ich versucht habe, Pandas zu verwenden, um die Formatierung zu tun, aber es funktioniert nicht auf füge dem Excel Farbe hinzu. Folgendes ist der Code:

writer = pandas.ExcelWriter(destination,engine = 'xlsxwriter') 
color = Answer.style.applymap(lambda x: 'color: red' if x == "Fail" else 'color: green',subset= pandas.IndexSlice[:,['Pass/Fail']]) 
color.to_excel(writer,'sheet1') 

Ich habe versucht, StyleFrame, die Installation fehlgeschlagen. Scheint, dass StyleFrame nicht meiner Python-Version 3.6 entspricht.

Wie kann ich das Excel so formatieren, wie ich möchte?

+0

Bitte setzen Sie die Rohdaten in Ihre Frage anstatt Bild – User193452

Antwort

2

können Sie conditional_format verwenden:

df = pd.DataFrame({'Pass/Fail':['Pass','Fail','Fail'], 
        'expect':[1,2,3]}) 
print (df) 
    Pass/Fail expect 
0  Pass  1 
1  Fail  2 
2  Fail  3 

writer = pd.ExcelWriter('pandas_conditional.xlsx', engine='xlsxwriter') 
df.to_excel(writer, sheet_name='Sheet1') 
workbook = writer.book 
worksheet = writer.sheets['Sheet1'] 
red_format = workbook.add_format({'bg_color':'red'}) 
green_format = workbook.add_format({'bg_color':'green'}) 

worksheet.conditional_format('B2:B4', {'type': 'text', 
             'criteria': 'containing', 
             'value':  'Fail', 
             'format': red_format}) 

worksheet.conditional_format('B2:B4', {'type': 'text', 
             'criteria': 'containing', 
             'value': 'Pass', 
             'format': green_format}) 
writer.save() 

Dynamischere Lösung mit get_loc für die Position von column und Kartierung mit dictionary:

import string 

df = pd.DataFrame({'Pass/Fail':['Pass','Fail','Fail'], 
        'expect':[1,2,3]}) 
print (df) 
    Pass/Fail expect 
0  Pass  1 
1  Fail  2 
2  Fail  3 

writer = pd.ExcelWriter('pandas_conditional.xlsx', engine='xlsxwriter') 
df.to_excel(writer, sheet_name='Sheet1') 
workbook = writer.book 
worksheet = writer.sheets['Sheet1'] 
red_format = workbook.add_format({'bg_color':'red'}) 
green_format = workbook.add_format({'bg_color':'green'}) 

#dict for map excel header, first A is index, so omit it 
d = dict(zip(range(25), list(string.ascii_uppercase)[1:])) 
print (d) 
{0: 'B', 1: 'C', 2: 'D', 3: 'E', 4: 'F', 5: 'G', 6: 'H', 7: 'I', 8: 'J', 
9: 'K', 10: 'L', 11: 'M', 12: 'N', 13: 'O', 14: 'P', 15: 'Q', 16: 'R', 
17: 'S', 18: 'T', 19: 'U', 20: 'V', 21: 'W', 22: 'X', 23: 'Y', 24: 'Z'} 

#set column for formatting 
col = 'Pass/Fail' 
excel_header = str(d[df.columns.get_loc(col)]) 
#get length of df 
len_df = str(len(df.index) + 1) 
rng = excel_header + '2:' + excel_header + len_df 
print (rng) 
B2:B4 

worksheet.conditional_format(rng, {'type': 'text', 
             'criteria': 'containing', 
             'value':  'Fail', 
             'format': red_format}) 

worksheet.conditional_format(rng, {'type': 'text', 
             'criteria': 'containing', 
             'value': 'Pass', 
             'format': green_format}) 
writer.save() 

EDIT1:

Danke jmcnamara für Kommentar und für XlsxWriter

col = 'Pass/Fail' 
loc = df.columns.get_loc(col) + 1 
len_df = len(df.index) + 1 

worksheet.conditional_format(1,loc,len_df,loc, {'type': 'text', 
             'criteria': 'containing', 
             'value':  'Fail', 
             'format': red_format}) 

worksheet.conditional_format(1,loc,len_df,loc, {'type': 'text', 
             'criteria': 'containing', 
             'value': 'Pass', 
             'format': green_format}) 
writer.save() 

EDIT:

Eine andere Lösung mit der letzten Version von Pandas (0.20.1) und styles:

df = pd.DataFrame({'Pass/Fail':['Pass','Fail','Fail'], 
        'expect':['d','f','g']}) 
print (df) 
    Pass/Fail expect 
0  Pass  d 
1  Fail  f 
2  Fail  g 

def f(x): 
    col = 'Pass/Fail' 
    r = 'background-color: red' 
    g = 'background-color: green' 
    c = np.where(x[col] == 'Pass', g, r) 
    y = pd.DataFrame('', index=x.index, columns=x.columns) 
    y[col] = c 
    return y 

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

Gibt es eine Möglichkeit, wie ich Spaltenname "Pass/Fail" anstelle von "B2: B4" verwenden kann? – user3843433

+0

Was ist x in def f (x)? Wenn Sie die Funktion später verwenden, gibt es kein x definiert – user3843433

+0

In 'style'' x' ist alles 'df', weil' Styler.apply' den Parameter 'axis = None' hat.Es ist dasselbe wie in klassischen Pandas 'f (df)'. Testen Sie es mit 'print (x)' – jezrael

1

Disclaimer: Ich schrieb folgendes Bibliothek

Ich mag StyleFrame mit vorschlagen:

import pandas as pd 
from StyleFrame import StyleFrame, Styler 

df = pd.DataFrame({'Pass/Fail':['Pass','Fail','Fail'], 
        'expect':[1,2,3]}) 

sf = StyleFrame(df) 

sf.apply_style_by_indexes(sf[sf['Pass/Fail'] == 'Pass'], cols_to_style='Pass/Fail', 
          styler_obj=Styler(bg_color='green')) 
sf.apply_style_by_indexes(sf[sf['Pass/Fail'] == 'Fail'], cols_to_style='Pass/Fail', 
          styler_obj=Styler(bg_color='red')) 

sf.to_excel('test.xlsx').save() 

Da es die Lücke zwischen Pandas und openpyxl überbrückt, das Styling auf der Ebene statt Datenrahmen der Arbeitsblatt-Ebene (so zum Beispiel getan wird brauchen Sie nicht zu weiß der relevante Zellbereich ist B2:B4 oder Chaos mit Indizes.

Der obige Code gibt die folgende:

enter image description here

EDIT: Gerade gesehen, die Sie erwähnt haben Sie versucht zu installieren, aber einen Fehler bekam. Können Sie Ihre Frage bearbeiten und den Fehler hinzufügen?

Verwandte Themen