Search code examples
pandasdataframedtype

How to fix FutureWarning: Setting an item of incompatible dtype in pandas


This is my script ...

from termcolor import colored
import pandas as pd
import numpy as np


data = {'Col1': [0, 15, 10, 5, 20, 17, 20], 'Col2': [11, 6, -3, 16, 21, 8, 26], 'STKS': [20, 30, 40, 50, 60, 70, 80], 'Col4': [3, 8, -13, -18, 3, 23, 42], 'Col5': [4, 19, 8, 11, 6, 20, 32]}

df = pd.DataFrame(data)
ATM = 50

def hightlight(series, excluded, spcl_col, spcl_val, extra_col= [] ):
        def excl_formatter(series):
            return [colored(str(x), 'white') for x in series]
    
        def norm_formatter(series, extra=False):
            tmp = series.sort_values()
            if extra:
                tmp.iloc[:-2] = tmp.iloc[:-2].map(lambda x: colored(x, *[('white' ,), ('green' ,),('light_red' ,),][np.sign(x)]))
                                             
            else:
                tmp.iloc[:-2] = tmp.iloc[:-2].map(lambda x: colored(str(x), 'white'))
            tmp.iloc[-2] = colored(tmp.iloc[-2], None, 'on_magenta')
            tmp.iloc[-1] = colored(tmp.iloc[-1], None, 'on_blue')
            return tmp
        
        def spcl_formatter(series):
            return [colored(x, None, 'on_blue') if x == spcl_val else colored(x, None,  'on_red') for x in series]
    
        if series.name == spcl_col:
            return spcl_formatter(series)
        if series.name in excluded:
            return excl_formatter(series)
        return norm_formatter(series, extra=series.name in extra_col)
        
col_to_exclude = ['STKS']
df_f1 = df.apply(hightlight, excluded=col_to_exclude, spcl_col='STKS',spcl_val=ATM, extra_col=['Col2', 'Col4']).rename(columns=lambda x: colored(x, 'white', None))
print(df_f1.to_string(index= False))

It was working well but after updating my python IDE it started to give future warning as ...

<string>:22: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['\x1b[97m0\x1b[0m' '\x1b[97m5\x1b[0m' '\x1b[97m10\x1b[0m'
 '\x1b[97m15\x1b[0m' '\x1b[97m17\x1b[0m']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
<string>:19: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['\x1b[91m-3\x1b[0m' '\x1b[32m6\x1b[0m' '\x1b[32m8\x1b[0m'
 '\x1b[32m11\x1b[0m' '\x1b[32m16\x1b[0m']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
<string>:19: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['\x1b[91m-18\x1b[0m' '\x1b[91m-13\x1b[0m' '\x1b[32m3\x1b[0m'
 '\x1b[32m3\x1b[0m' '\x1b[32m8\x1b[0m']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.
<string>:22: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['\x1b[97m4\x1b[0m' '\x1b[97m6\x1b[0m' '\x1b[97m8\x1b[0m'
 '\x1b[97m11\x1b[0m' '\x1b[97m19\x1b[0m']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.

I got a solution to hide this warning by following....

import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)

Is there any way to handle this dtype caused warning plz.


Solution

  • The issue is due to tmp being of int64 dtype and trying to assign strings to it.

    Define tmp as an object Series in norm_formatter:

    def norm_formatter(series, extra=False):
        tmp = series.sort_values().astype(object)
        # ... rest of code ...
    

    Which will avoid the warning.