1

I have two dataframes containing dates:

df1:

Name  A             B             C  
D1    2018-04-26    2018-04-24    2018-04-24
D2    2018-04-25    2018-04-23    2018-04-23
D3    2018-04-25    2018-04-26    2018-04-26

df2:

Name  A             B             C  
D1    2018-04-24    2018-04-23    2018-04-24
D2    2018-04-25    2018-04-23    2018-04-21
D3    2018-04-22    2018-04-24    2018-04-23

Let's say i would like to style df1 such that if a value does not equal the corresponding value in df2, it highlights the cell red.

I know i need to create a function and use

df1.style.applymap()

but i'm having trouble putting the function together. Something like;

def diffindicator(val):
    color = 'white'   
    if val != df2:
        color = 'red'
    return 'background-color: %s' % color
Joel
  • 99
  • 8
  • `... i'm having trouble putting the function together...` - What does your function do, how is it deficient? – wwii Apr 30 '18 at 14:44
  • When I try to apply the function using df1styler= df1.style.applymap(diffindicator) I get keyerrors on my indexes – Joel Apr 30 '18 at 14:48
  • Have you tried any other methods? – wwii Apr 30 '18 at 14:54
  • So I just tried `def diffindicator(val): color = 'white' for c,r in df2.iterrows(): if val != df2[c,r]: color = 'red' return 'background-color: %s' % color` But not im getting errors iterating over df2 – Joel Apr 30 '18 at 14:58

1 Answers1

2

Here's one way to go about highlighting the difference:

# Load Example Data
df1 = pd.read_fwf(StringIO(
'''Name  A             B             C  
D1    2018-04-26    2018-04-24    2018-04-24
D2    2018-04-25    2018-04-23    2018-04-23
D3    2018-04-25    2018-04-26    2018-04-26'''))
df2 = pd.read_fwf(StringIO(
'''Name  A             B             C  
D1    2018-04-24    2018-04-23    2018-04-24
D2    2018-04-25    2018-04-23    2018-04-21
D3    2018-04-22    2018-04-24    2018-04-23'''))

def highlight_diff(data, other, color='pink'):
    # Define html attribute
    attr = 'background-color: {}'.format(color)
    # Where data != other set attribute
    return pd.DataFrame(np.where(data.ne(other), attr, ''),
                        index=data.index, columns=data.columns)

# Set axis=None so it passes the entire frame
df2.style.apply(highlight_diff, axis=None, other=df1)

Output:

Difference between Frames

Also, take a look at this question for a closer look on the subject of getting the difference between DataFrames... In fact, my answer may or may not be inspired by this answer.

Aaron N. Brock
  • 4,276
  • 2
  • 25
  • 43
  • 1
    I don't have the required dependencies here at work. I came up with `def styl(df, other): st = df.where(df == other, 'background-color:red'); st = st.where(df != other, 'background-color:white'); return st` for the function, would you mind checking that? – wwii Apr 30 '18 at 15:34
  • @wwii is this in order to get the red/white background? – Aaron N. Brock Apr 30 '18 at 15:36
  • @wwii I edited my answer to make the color red. (Or pink actually, nice red looked nasty) – Aaron N. Brock Apr 30 '18 at 15:48
  • Sorry, I was asking for a favor: if you could check my function to see if it works, I can't check it here at work. – wwii Apr 30 '18 at 15:55
  • @wwii Oh, I understand now, yes, it works: https://screenshots.firefox.com/HkmlTbV8tMpNl1j8/docker4.devops.iconectiv.com – Aaron N. Brock Apr 30 '18 at 16:01
  • Thanks @wwii, using your solution i was easily able to highlight df1 with different colors depending on if it was ahead of or behind df2 – Joel Apr 30 '18 at 18:05