DataFrameの計算でWarningが出た！その理由は

DataFrame同士で計算を行っていると、次のWarningが出る事があります。
このエラーは、例えば、「カラム名を同じもので上書きしようとした場合」に出るはずです。

```
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
```

Warningの意味は、「もとのDataFrameからコピーした。（=もとのDFは上書きしなかった）」というものです。
しかし、欲しい結果は得られているのではないでしょうか。
結果は正しいのですが、Pythonは「この結果は、あなたが望んだ結果ではないかもしれないので、注意して」と言っているのです。

※ここではDataFrameを「**df**」（または**DF**)と表記します。
※ここで使用したcsvファイル、コード全文は、ページ下部の参考ページのリンクから参照可能です。
#内容
- どんな時に起きるか
- 原因
- 解決方法
- 参考ページ
<br>https://shilabo.com/python/web_self/
<br>https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html

#【どんな時に起きるか】
これは、例えば、%表示の変換で、「1.00(%)」となっているものを数値「0.01」に同じカラム名で変換（上書き）しようと、

`df2['pct'] = df2['pct'] / 100`

と書いた場合に起きると思います。それは、コードを辿ると、df2が他のDFを参照し

`df2 = df1[['clm0', 'clm1']]`

のように書いているのではないでしょうか？

#【原因】
これは　**_chained indexing_** と呼ばれるものです。

dfを連鎖的にカラム名を指定して参照（複製）した場合に起きます。
例えば、df1が所与の時、新しいdf2に対して、

`df2 = df1[['clm0', 'clm1']]`と書いて、更に`df2['clm0'] =1`のように、

辿った先の、元のdf1を、df1のカラム名を使って上書きする（上書きするのと同じコードを書いた）ような場合に起きます。

`df2 = df1`と書けば、`df2['clm0']=1`(カラム’clm0’を全部1にする)と書いても問題は起きません。それは、df1の全てがdf2に複製され、df2をいじると、df1も同時に上書きされるからです。

ところが、カラム名を指定して、`df2 = df1[['clm0', 'clm1']]`と書くと、df2には写しが渡されますが、ここでdf1に存在するカラム名’clm0’を指定してdf2の方から`df2['clm0']=1`と書くと、Pythonはdf1は上書きしない、という判断をします。

本来、`df2 = df1`という書き方は、df2をいじれば、df1も上書きする、という仕様です。しかし、`df2['clm0']=1`と書くと、この仕様とは異なるので、Warningを出すと思われます。

Warningの指示通り、df.loc[]を使っても(例えば、`df.loc[:,'pct']`)、同じWarningが出るはずです。

まず、仕様を確認します。

```Python
import pandas as pd
f1 = r'C:\Users\shilabo\Documents\SHiLABO_python\a004_007a.csv'
df1 = pd.read_csv(f1)

#1.1(a) example
df2A = pd.read_csv(f1)
df2a = df2A
df2a['clm0'] = 99
print('#df2a\n', df2a)
#df2a
#    clm0  clm1  clm2  clm3
#0    99    -1    12   105
#1    99    -2    22   205
#2    99    -3    32   305
#3    99    -4    42   405
#4    99    -5    52   505

print('#df2A\n', df2A)
#df2A
#    clm0  clm1  clm2  clm3 #<=df2Aも'clm0'が上書きされる。
#0    99    -1    12   105
#1    99    -2    22   205
#2    99    -3    32   305
#3    99    -4    42   405
#4    99    -5    52   505
view rawa004_007_02.py hosted with ❤ by GitHub
```

次にWaningを再現します。

```Python
df2B = pd.read_csv(f1)
df2b = df2B[['clm0', 'clm1']]
df2b['clm0'] = 99
print('#df2b\n',df2b)　
#df2b               #<=df2bはWarningが出て、上書きされる。
#    clm0  clm1
#0    99    -1
#1    99    -2
#2    99    -3
#3    99    -4
#4    99    -5
#A value is trying to be set on a copy of a slice from a DataFrame.
#Try using .loc[row_indexer,col_indexer] = value instead

print('#df2B\n',df2B)
#df2B
#    clm0  clm1  clm2  clm3 #<=df2Bは'clm0'が上書きされない。
#0     1    -1    12   105
#1     2    -2    22   205
#2     3    -3    32   305
#3     4    -4    42   405
#4     5    -5    52   505
```

#【解決方法】
1. 同じ名前のカラム名で、結果を入れた新しいカラムを作るのを「避ければ」、このWarningは回避できます。
<br>または、
2. 同じカラム名にしたければ、以下のように、`df2 = df1['clm0'].copy()`と書いて、コピーである事を明確にすれば、Warningは出ません。

```Python
df2C = pd.read_csv(f1)
df2c = df2C[['clm0', 'clm1']].copy() #.copy()とする。
df2c['clm0'] = 99
print('#df2c\n',df2c)
#df2c
#    clm0  clm1 #<=df2cで'clm0'を上書きしてもWarningは出ない。
#0    99    -1
#1    99    -2
#2    99    -3
#3    99    -4
#4    99    -5

print('#df2C\n',df2C)
#df2C
#    clm0  clm1  clm2  clm3 #<=df2Cは上書きされない。
#0     1    -1    12   105
#1     2    -2    22   205
#2     3    -3    32   305
#3     4    -4    42   405
#4     5    -5    52   505
```

勿論、Warningの内容を分かっていて使っていれば、多くの場合、問題ありません。

#参考ページ
- 実践で使うPythonの技術が掲載されています。書籍のように構成されています。

https://shilabo.com/python/web_self/

- pandasの該当部分のドキュメント（英語）です。<br>
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html
- コードに用いたcsvファイル(GitHub) : [a004_007a.csv](https://gist.githubusercontent.com/shilabo/347fa89bb661010b90f76aec79d3c6b1/raw/a7092285fa7d06b5d9e898eb31441a13650c3279/a004_007a.csv)
- ここに掲載したコード全文

https://gist.github.com/shilabo/3e97fddac134dc8df1492f8e11fe535f#file-a004_007_02-py