web-dev-qa-db-ja.com

Pandas .locを使用した後でも、SettingWithCopyWarningを取得しています

最初は、次のようなコードを書いてみました。

import numpy as np
import pandas as pd
np.random.seed(2016)
train = pd.DataFrame(np.random.choice([np.nan, 1, 2], size=(10, 3)), 
                     columns=['Age', 'SibSp', 'Parch'])

complete = train.dropna()    
complete['AgeGt15'] = complete['Age'] > 15

SettingWithCopyWarningを取得した後、using.locを試しました。

complete.loc[:, 'AgeGt15'] = complete['Age'] > 15
complete.loc[:, 'WithFamily'] = complete['SibSp'] + complete['Parch'] > 0

ただし、それでも同じ警告が表示されます。何が得られますか?

19
Huey

注:pandasバージョン0.24以降、_is_copy_は非推奨になり、将来のバージョンで削除される予定です。プライベート属性__is_copy_は存在しますが、アンダースコアはこの属性がパブリックAPIの一部ではないため、依存すべきではありません。したがって、今後、SettingWithCopyWarningを無音にする唯一の適切な方法は、グローバルにそうすることであると思われます。

_pd.options.mode.chained_assignment = None
_

complete = train.dropna()が実行されると、dropnaがコピーを返す可能性があるため、十分な注意を払って、Pandasは_complete.is_copy_をTruthy値に設定します:

_In [220]: complete.is_copy
Out[220]: <weakref at 0x7f7f0b295b38; to 'DataFrame' at 0x7f7eee6fe668>
_

これにより、Pandasは、後で_complete['AgeGt15'] = complete['Age'] > 15_が実行されたときに、trainに影響を与えないコピーを変更している可能性があることを警告できます。初心者の場合は次のようになります。有用な警告。あなたの場合、trainを変更することによって間接的にcompleteを変更する意図はないようです。したがって、警告はあなたの場合には意味のない迷惑です。

次のように設定すると、警告を消音できます。

_complete.is_copy = False       # deprecated as of version 0.24
_

これは実際のコピーを作成するよりも速く、つぼみのSettingWithCopyWarningをニップします(ポイント __check_setitem_copy_が呼び出される場所 ):

_def _check_setitem_copy(self, stacklevel=4, t='setting', force=False):
    if force or self.is_copy:
        ...
_

自分が何をしているのかを本当に確信している場合は、SettingWithCopyWarningをグローバルにシャットオフできます。

_pd.options.mode.chained_assignment = None # None|'warn'|'raise'
_

警告を消音する別の方法は、新しいコピーを作成することです。

_complete = complete.copy()
_

ただし、DataFrameが大きい場合は、コピーにかなりの時間とメモリがかかる可能性があり、(警告を消音するためを除いて)まったく意味がないため、これを実行したくない場合があります。 completeがすでにコピーであることがわかっている場合。

19
unutbu

データフレームのコピーを作成して解決します。

complete = train.copy()
2
nnaqa

元のデータフレームの_.loc_がなければ、_np.nan_ソリューションは機能すると思います。 complete = train.dropna().reset_index()または Pandas .assign()SettingWithCopyWarningを回避し、新しい列を作成して新しいデータフレームオブジェクトを返すための推奨される方法です。あなたの例:

_complete = complete.assign(**{'AgeGt15': np.where(complete['Age'] > 15, True, False)})
_
0
Jamie Edgecombe