0

Why is this? I'm going to make 4 dataframes in pandas:

>>> df = pd.DataFrame({"A": ["One","Two","Three"], "B": ["Two","Three","Four"], "C": ["Three","Four","Five"], "D": ["Four","Five","Six"]})
>>> df
       A      B      C     D
0    One    Two  Three  Four
1    Two  Three   Four  Five
2  Three   Four   Five   Six
>>> df["C"][1] = "One Hundred"

Everything worked well; now let's do two columns first then we add two columns, one with "" and the other one with NaN

>>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
>>> df
   A  B
0  1  2
1  2  3
2  3  4
>>> df["C"] = ""
>>> df["D"] = pd.np.nan
>>> df
   A  B C   D
0  1  2   NaN
1  2  3   NaN
2  3  4   NaN
>>> df["C"][1] = "hello"

Warning (from warnings module):
  File "__main__", line 1
SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

A Warning shows up! Ok: (this is the question: what is that warning for?) But let's continue:

now I do this:

>>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4], "C": [3,4,5], "D": [4,5,6]})
>>> df
   A  B  C  D
0  1  2  3  4
1  2  3  4  5
2  3  4  5  6
>>> df["C"][1] = 100

and no Warning appears. ok.

Now let's trigger the warning again:

>>> df = pd.DataFrame({"A": [1,2,3], "B": [2,3,4]})
>>> df["C"] = ""
>>> df["D"] = pd.np.nan
>>> df
   A  B C   D
0  1  2   NaN
1  2  3   NaN
2  3  4   NaN
>>> df["C"][1] = "hello"
>>> 

NO WARNING THIS TIME!?

I'm using IDLE 3.5.2 , Python version: 3.5.2...

Is this a bug? I can't tell because I'm studying.

Should I write a new separate DataFrame with all the column and then just equal it to the df's column each time?

Should I make a python list?...

Is there a way to traverse and edit over the original dataframe without the warning?

Why isn't that warning popping up every time?

Thanks for your time.

Phil Rv
  • 75
  • 1
  • 1
  • 6

3 Answers3

0

You can using loc or iloc

df
Out[1445]: 
     A  A_1    B
0  1.0  1.0    A
1  NaN  NaN    A
2  3.0  3.0  NaN
3  4.0  4.0    B
df.iloc[1,1]='Yourvalue1'
df
Out[1447]: 
     A         A_1    B
0  1.0           1    A
1  NaN  Yourvalue1    A
2  3.0           3  NaN
3  4.0           4    B
df.loc[1,'A']
Out[1448]: nan
df.loc[1,'A']='Yourvalue2'
df
Out[1450]: 
            A         A_1    B
0           1           1    A
1  Yourvalue2  Yourvalue1    A
2           3           3  NaN
3           4           4    B
BENY
  • 317,841
  • 20
  • 164
  • 234
0

I think the right way to do it is to write a function and use it with the apply method.

df.apply(my_function, axis=1)

like shown here so that pandas can do its thing super fast.

Phil Rv
  • 75
  • 1
  • 1
  • 6
-3

The correct way is:

df["column_name"][0] = "hello"

If you use the dot column_name way you are selecting a slice apparently. if you use this (correct) method you are "touching the cell" so to speak.

Phil Rv
  • 75
  • 1
  • 1
  • 6
  • 2
    This is *not* the correct way, as the documentation the warning message provided a link to explained. – DSM Jan 28 '18 at 00:42
  • @PhilRv, chained expressions are not promoted by `pandas`. Documentation prefers `df.loc` or `df.iloc` in such cases. – jpp Jan 28 '18 at 00:47
  • This gives me the exact same warning message. – Aran-Fey Jan 28 '18 at 00:50