9

Here is my df:

In[12]: df  = pd.DataFrame(data = list("aabbcc"), columns = ["s"], index=range(11,17))
In[13]: df
Out[13]: 
    s
11  a
12  a
13  b
14  b
15  c
16  c

Let's try to replace values based on index:

In[14]: df.loc[11, "s"] = 'A'
In[15]: df
Out[15]: 
    s
11  A
12  a
13  b
14  b
15  c
16  c
In[16]: df.ix[12, "s"] = 'B'
In[17]: df
Out[17]: 
    s
11  A
12  B
13  b
14  b
15  c
16  c

It works! But if I do the same based on position, not index, say something like this, but it shows ValueError (ValueError: Can only index by location with a [integer, integer slice (START point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array]):

In[18]: df.iloc[1, "s"] = 'b'

And, if I try something like this:

df.s.iloc[1] = "b"

I get this warning :

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame
ramesh
  • 1,187
  • 7
  • 19
  • 42
  • 2
    The first error you are getting is because you are trying to use integer based indexing with a string. try `df.iloc[1, 0] = 'b'`. Is this the full code that you are running? `df.s.iloc[1] = "b"` does not produce an error when I run it. I would expect to see the warning you are getting if `df` was created by slicing another dataframe. – johnchase Aug 04 '16 at 20:29

1 Answers1

15

You can use get_loc to get the location of the column and pass that to iloc:

df.iloc[1, df.columns.get_loc('s')] = 'B'

df
Out: 
    s
11  a
12  B
13  b
14  b
15  c
16  c

Or the other way around:

df.loc[df.index[1], 's'] = 'B'
ayhan
  • 70,170
  • 20
  • 182
  • 203
  • 4
    I fail to understand the design of this behavior. Why would it make sense to force the user to provide the index of a named column by an extra function call? – Gulzar May 16 '21 at 10:05