I am just beginning to learn pandas and am looking to provide some automated help. From what I read, it appears that SettingWithCopyWarning is something that confuse many people. Is the following correct?
`SettingWithCopyWarning`:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Pandas occasionally emits a SettingWithCopyWarning when you use
'chained indexing', either directly or indirectly,and you then attempt
to assign a value to the result. By 'direct chained indexing', we mean
that your code contains something like:
...[index_1][index_2] = ...
During the first extraction using [index_1], pandas found that the
series to be created contained values of different types. It
automatically created a new series converting all values to a common
type. The second indexing, [index_2] was then done a this copy instead
of the original dataframe. Thus, the assigment was not done on the
original dataframe, which caused Pandas to emit this warning.
An 'indirect chained indexing' essentially amount to the same problem
except that the second indexing is not done on the same line as that
which was done to extract the first series.
You used direct chained indexing of a dataframe which made a copy of
the original content of the dataframe. If you try to assign a value to
that copy, the original dataframe will not be modified. Instead of
doing a direct chained indexing
df.loc["b"]["x"] ...
try:
df.loc["b", "x"] ...
`SettingWithCopyWarning`:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Warning issued on line 4 of code block [6].
1| # What about if I tried to use indirect chaining.
2| # There are two possibilities
3| series = df.loc["b"]
> 4| series["x"] = 99
I suspect that you used indirect chained indexing of a dataframe.
First, you likely created a series using something like:
series = df.loc[...]
This made a copy of the data contained in the dataframe. Next, you
indexed that copy
series["x"]
This had no effect on the original dataframe. If your goal is to
modify the value of the original dataframe, try something like the
following instead:
df.loc[..., "x"]
`SettingWithCopyWarning`:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Warning issued on line 3 of code block [9].
1| # What if I do things in a different order
2| series_1 = df["x"]
> 3| series_1.loc["b"] = 99
I suspect that you used indirect chained indexing of a dataframe.
First, you likely created a series using something like:
series_1 = df[...]
This made a copy of the data contained in the dataframe. Next, you
indexed that copy
series_1.loc["b"]
This had no effect on the original dataframe. If your goal is to
modify the value of the original dataframe, try something like the
following instead:
df.loc[..., "b"]
`SettingWithCopyWarning`:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
Warning issued on line 4 of code block [12].
2| df2 = df.copy()
3| series = df.loc["b"]
> 4| series["x"] = 99
In your code, you have the following dataframes: {'df2', 'df'}. I do
not know which one is causing the problem here; I will use the name
df2 as an example.
I suspect that you used indirect chained indexing of a dataframe.
First, you likely created a series using something like:
series = df2.loc[...]
This made a copy of the data contained in the dataframe. Next, you
indexed that copy
series["x"]
This had no effect on the original dataframe. If your goal is to
modify the value of the original dataframe, try something like the
following instead:
df2.loc[..., "x"]
No comments:
Post a Comment
Spammers: none shall pass.
Note: Only a member of this blog may post a comment.