49326


pandasのデータフレーム(df2)から必要な行列だけを抜き出すために、下記のような操作をした際に表示されるワーニングについて。

[code]

    df2 = df.iloc[0:3201,:] 
    #必要なデータだけ抜き出し
    df2 = df2.astype(float)
    #データ型変更:実数
    df_index = df2.iloc[:,0]
    df_alfa = df2.iloc[:,np.arange(1, 27, 3)]
    
[/code]

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: <http://pandas.pydata.org/pandas-
docs/stable/indexing.html#indexing-view-versus-copy>

ilocではなく、locで”カラム名で指定”を推奨していることなのでしょうか？  
計算、グラフ作成は問題なくできているのですが、気になっております。

<質問追記2018/10/16>  
magichansさんへ  
プログラムを再度確認してみると、  
上記ではなく下記のところで表示されているエラーのようです（すみません）。  
次のような計算にすすみ、

[code]

    index=df_alfa.index
    ave = df_alfa.mean(axis=1) 
    std = df_alfa.std(axis=1)
    
[/code]

ここまで問題なし。  
次の２行でをアクティブにするとエラーが表示されるとわかりました。

[code]

    df_alfa["ave"] = ave
    df_alfa["STD"] = std
    
[/code]

平均と標準偏差を行毎に算出して、  
その計算結果を元のデータフレームdf_alfaに追加するために、上記を行なっています。  
その後、グラフ化へ。。

ここの指定の方法に問題ありますでしょうか？

Yasuhiroさんへ  
<質問追記2018/10/16>  
もともと読み込んだデータの一部の行列に"NaN"や"Int"が含まれていて、floatで読み込みたい数値がobjectになっていたため、NaNやIntの処理後に必要なデータ全体を一括float指定するために行った操作です。ここはオリジナルデータ(df2)を上書き変更していると思っておりましたが、コピーが生成されるということなのですね？オリジナルを上書きする方法はございますか？もしくは、

[code]

    df3 = df2.astype(float)
    
[/code]

と別名にした方が賢明？？ 混同・思い違いを避けるために。

Yasuhiroさんへ  
<質問追記2018/10/16 その２>  
ありがとうございます。

[code]

    df2 = df.iloc[0:3201,:] 
    df2 = df2.astype(float)　#ここでコピーが作成される
    
    df2 = df2.set_index(0)
    df_alfa = df2.iloc[:,np.arange(1, 27, 3)]
    df2["ave"] = df_alfa.mean(axis=1) 
    df2["STD"] = df_alfa.std(axis=1)
    
[/code]

についてですが、最終的には必要な列をピックアップした”df_alfa”に  
、”df_alfa"のデータから算出した”ave”と”STD”の２列を追加して"df_alfa"を可視化  
という流れが私のやりたいことなのですが、その場合、上記の最後の２行は、

[code]

    df_alfa["ave"] = df_alfa.mean(axis=1) 
    df_alfa["STD"] = df_alfa.std(axis=1)
    
[/code]

と変更しても大丈夫ですか？  
なんとなく不安なので、一旦、データフレーム外に算出して（書き出して）、  
計算後にそれら２列を追加したのですが。  
"平均と標準偏差の計算"と"２つの列の追加”の処理がぶつからないかと心配？？  
もし、そうであれば（邪魔するのであれば）、

[code]

    ave = df_alfa.mean(axis=1) 
    std = df_alfa.std(axis=1)
    
[/code]

として、その後

[code]

    df_alfa["ave"] = ave
    df_alfa["STD"] = std
    
[/code]

と２段階で２列を追加した方が賢明？？  
(10/16 20:00時点：こちらで上記についてプログラム走らせて確認した結果、２段階に分けてしないと計算結果が合いませんでした。)

そもそもここで、index,ave,stdを書き出したのは、後のmatplotlib.pyplotでの  
データ可視化（グラフに表示させる）のために指定しました。

[code]

    ax = fig.add_subplot(111)
    ax.plot(index, ave)
    ax.errorbar(index,ave,yerr=std,...)
    
[/code]

ここで、pandasのDataFrame.plotを使えば、こんな指定は必要なく、  
DataFrameの列名で指定できるので簡単なのですが...。  
エラーバーの表示でpandasのplotで上手く行かない事があり..  
この件は、別に質問あげる予定です。


CC BY-SA 4.0
2018-10-15T14:34:29.850
49314
2018-10-17T09:54:23.207
2018-10-16T11:02:15.927
30391
30391
question
python pandas numpy
pandas.dataframeからilocを用いて必要なデータだけを抜き出した際に表示されるワーニングについて教えてください。


Warning のリンク先 <http://pandas.pydata.org/pandas-
docs/stable/indexing.html#indexing-view-versus-copy> をみると以下のような記述があります。質問で出ている
Warning は、バグによるものではないでしょうか。

> Sometimes a SettingWithCopy warning will arise at times when there’s no
> obvious chained indexing going on. These are the bugs that SettingWithCopy
> is designed to catch! Pandas is probably trying to warn you that you’ve done
> this:
[code]

>     def do_something(df):
>        foo = df[['bar', 'baz']]  # Is foo a view? A copy? Nobody knows!
>        # ... many lines here ...
>        foo['quux'] = value       # We don't know whether this will modify df
> or not!
>        return foo
>  
[/code]

>
> Yikes!

**< 質問追記2018/10/16>magichansさんへに対する回答**

ドキュメントのバグの例と同様のケースなのでpandasのバグだと思います。ただ、pandaの場合どんどん変数を作っていくのは、ViewかCopyかわからなくなってしまうので、あまり賢明な方法ではないと思います。以下のように`df_alfa`ではなくて`df2`を使って作業するとwarningも消えるし、メモリーの消費も減ると思います。

[code]

    df2 = df.iloc[0:3201,:] 
    df2 = df2.astype(float)　#ここでコピーが作成される
    
    df2 = df2.set_index(0)
    df_alfa = df2.iloc[:,np.arange(1, 27, 3)]
    df2["ave"] = df_alfa.mean(axis=1) 
    df2["STD"] = df_alfa.std(axis=1)
    
[/code]

**< 質問追記2018/10/16>Yasuhiroさんへに対する回答**

質問のコードだけでワーニングになる理由がよくわからなくて書いたので、`df2 = df2.astype(float)`で問題はありません。

なお、`df2 = df.iloc[0:3201,:]`では、df2はdfのViewですが、 `df2 =
df2.astype(float)`とすることで新しいコピーが作成されて、dfとは別のメモリー空間になります。それで、df2に変更を加えたらdfが変更されてしまうという副作用が起こらなくなります。


CC BY-SA 4.0
2018-10-16T00:37:54.863
49323
2018-10-16T06:56:26.917
2018-10-16T06:56:26.917
15171
15171
49314
answer


簡単に説明しますと、Warningのリンク先にも記述されておりますが。  
例えば

[code]

    df_tmp = df.iloc[10:20]
    df_tmp[5] = 55
    
[/code]

のように記述された場合、開発者の意図としては

【１】 df から10行目から19行目を df_tmp にコピーして、そのコピー先の df_tmp に対してのみ 5列目を更新したい

【２】 （df_tmp は df の単なるViewであり）開発者は df に対して 10行目から19行目の 5列目 を更新したい

のどちらか（判別が付きませんが）となります。

で、もしこの【２】の意図として書いているのであれば、

[code]

    df.iloc[10:20, 5] = 55
    
[/code]

と書いてね。というのがこの Warningの意味となります。

上記の例ではあまり問題にならないかもしれませんが、上記のコードを１行でまとめて

[code]

    df.iloc[10:20][5] = 55
    
[/code]

のように記述されると問題が顕著化します。

ですので【１】の意図として使用しているのであれば、Warningを無視していただいて構いません。  
どうしても気になるのであればdf_tmpはViewとしてのではなくコピーとして使用する事を明示的に

[code]

    df_tmp = df.iloc[10:20].copy()
    df2 = df_tmp[5]
    
[/code]

と示すとよいかとおもいます。

で、現在のコードを確認すると

[code]

    df_alfa = df2.iloc[:,np.arange(1, 27, 3)]
    df_alfa["ave"] = ave
    
[/code]

という処理をしているようですので、この部分が上記の Warningの対象となったのかと思います。


CC BY-SA 4.0
2018-10-16T01:52:35.370
49326
2018-10-17T09:54:23.207
2018-10-17T09:54:23.207
754
24801
49314
answer