0

I have a Pandas dataframe that contains data of prices of various products as taken on different dates, the columns are ‘date’, ‘product’, ‘price’.

My goal is to highlight the price cell where there has been a price reduction for that particular product. Much like this example .csv seen below…

An example .csv showing what I want to achieve using Pandas Styling

I understand that each product will need to be separated and then the prices of that product evaluated in pairs. I have used the following code in another part of the script to successfully achieve this:

integer = 0

for iteration in range(iterations):   

    first_price_pair = one_product.iloc[integer,2] 
    integer=integer+1
    second_price_pair = one_product.iloc[integer,2] 

# one_product is selected by using .drop_duplicates() on 'product'


price_dif = first_price_pair - second_price_pair                                

    if second_price_pair < first_price_pair:
        # highlight cell green - INDICATES PRICE REDUCTION FROM PREV PRICE                                
       
    elif second_price_pair == first_price_pair:         
        # no change to cell colour  
        
    elif second_price_pair > first_price_pair:
        # highlight cell RED - INDICATES PRICE INCREASE FROM PREV PRICE

My problem is when I attempt to use - DataFrame.style - for applying the highlighting. It appears that once ‘styling’ has been applied to the DF, the DF is then converted to type: pandas.io.formats.style.Styler - and that this can then not be modified.

I’d appreciate it if someone can confirm it is possible to achieve what I’m trying to do and if so, give me some guidance on how to achieve it.

Thank you!

Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • Styling is meant for output and easy readership, it's not meant to continuing operations on a dataframe. You can write a function to pretty-print the DataFrame – Code Different May 08 '20 at 21:51

1 Answers1

0

To apply highlights you might want to use either:

Styler.applymap()
Styler.apply()

The difference between the two lies in the way you want to select the elements as applymap() works elementwise and apply() works with column-/row-/table-wise.

Both methods require a function to generate the CSS attributes you want to change. In your case if you put it in an if statement it might be something like this:

import pandas as pd
df = pd.DataFrame(np.random.randint(-4,4, size=(5,5)))
def background_cell(x, row_idx, col_idx, color):
    b_color = 'background-color: green'
    df_styler = pd.DataFrame('', index=x.index, columns=x.columns)
    df_styler.iloc[row_idx, col_idx] = b_color
    return df_styler

df.style.apply(background_cell, row_idx=1, col_idx=1, color='green', axis=None)

This is going to change the background of the cell [1,1]. You can call df.style.apply() with a different colour and the index of the cell you want to change.

I think you overwrote the Styler on the DataFrame variable by typing df = df.style.apply(...) that's why you lost it and couldn't modify it anymore. The styling is a method you can use to show the DataFrame, so you should use it whenever you are printing it, although it won't be an attribute of the DataFrame itself.

Hexash
  • 48
  • 6