Home > database >  How to avoid 'SettingWithCopyWarning' without using 'loc'?
How to avoid 'SettingWithCopyWarning' without using 'loc'?

Time:02-16

I have read many postings about 'SettingWithCopyWarning'. Using 'loc' seems to be the most straightforward way to avoid this warning.

However, it is hard to use loc when the index is DatetimeIndex as like df in the following code.

import pandas as pd
import numpy as np
from datetime import datetime

df = pd.DataFrame(index=pd.date_range(datetime.today(), periods=6), columns=['a', 'b'])
df['c'] = 10 
print(df)

                              a    b   c
2022-02-16 15:31:09.927441  NaN  NaN  10
2022-02-17 15:31:09.927441  NaN  NaN  10
2022-02-18 15:31:09.927441  NaN  NaN  10
2022-02-19 15:31:09.927441  NaN  NaN  10
2022-02-20 15:31:09.927441  NaN  NaN  10
2022-02-21 15:31:09.927441  NaN  NaN  10

In this situation, I am using df.loc[df.index==df.index[1],'a'] = 10 as recommended by many postings. However, typing df.index==df.index[1] every time is cumbersome.

Sp, I am wondering if there is a simple way to index such a df with an index number and column name. For example, df['a'][1]=10 is simple and intuitive, but it returns the 'SettingWithCopyWarning' warning.

Thank you for any comment in advance.

CodePudding user response:

Use:

df.iloc[1, df.columns.get_loc('a')]=10

The output:

enter image description here

CodePudding user response:

You could define a wrapper to do the job for you:

def get(df,idx,col,val=None):
    if not isinstance(idx, list):
        idx = [idx]
    if val:
        df.loc[df.index.isin(df.index[idx]), col] = val
    else:
        return df.loc[df.index.isin(df.index[idx]), col]

# getting value
get(df,1,'a')
# 2022-02-17 04:58:58.655186    10
# Freq: D, Name: a, dtype: object

# setting value(s) in place
get(df,1,'a',10)
get(df,[3,4],['a','b'],99)

Updated DF:

                              a    b   c
2022-02-16 04:58:58.655186  NaN  NaN  10
2022-02-17 04:58:58.655186   10  NaN  10
2022-02-18 04:58:58.655186  NaN  NaN  10
2022-02-19 04:58:58.655186   99   99  10
2022-02-20 04:58:58.655186   99   99  10
2022-02-21 04:58:58.655186  NaN  NaN  10
  • Related