Home > Software design >  Setting value using both loc and iloc pandas
Setting value using both loc and iloc pandas

Time:04-29

We have data, which is represented below:

import pandas as pd
import numpy as np

d = {'shift_city_id': [1, 1,2,3,3,3,1], 'closest_city_id': [np.nan, np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]}
df = pd.DataFrame(data=d)
df

  shift_city_id  closest_city_id
0      1           NaN
1      1           NaN
2      2           NaN
3      3           NaN
4      3           NaN
5      3           NaN
6      1           NaN

The goal is to input specific values in a cell with particular city_id, one by one. So I try this:

df.loc[lambda x: (x['shift_city_id']==3),'closest_city_id'].iloc[0]=3
df.loc[lambda x: (x['shift_city_id']==3),'closest_city_id'].iloc[1]=4
df.loc[lambda x: (x['shift_city_id']==3),'closest_city_id'].iloc[2]=5

and get no change at all in dataframe, np.nan is still there. While the result should be:

    shift_city_id   closest_city_id
0     1                 NaN
1     1                 NaN
2     2                 NaN
3     3                 3
4     3                 4  
5     3                 5
6     1                 NaN

What can solve the problem?

CodePudding user response:

You could do:

df.loc[lambda x: (x['shift_city_id']==3),'closest_city_id'] = [3,4,5]

which gives the wanted output:

enter image description here

To understand the different behaviour of the assignation, I defer to these detailed answers

CodePudding user response:

Dynamic so that you could do more than one id/values set at a time:

ids = [3]
id_values = {3: [3, 4, 5]}
df['closest_city_id'] = df[df['shift_city_id'].isin(ids)]['shift_city_id'].replace(id_values)

Output:

   shift_city_id  closest_city_id
0              1              NaN
1              1              NaN
2              2              NaN
3              3              3.0
4              3              4.0
5              3              5.0
6              1              NaN

CodePudding user response:

Here lambda is not necessary, you can compare column df['shift_city_id'] and because 3 rows matched is possible assign list with length 3:

df.loc[df['shift_city_id']==3,'closest_city_id'] = [3,4,5]
print (df)
   shift_city_id  closest_city_id
0              1              NaN
1              1              NaN
2              2              NaN
3              3              3.0
4              3              4.0
5              3              5.0
6              1              NaN
  • Related