2016-08-07 16 views
6

Zuerst bekommen, habe ich versucht, einige Code schreiben, der so aussah:Pandas noch SettingWithCopyWarning auch nach der Verwendung von .loc

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 

Nach SettingWithCopyWarning bekommen, habe ich versucht, using.loc:

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

jedoch Ich bekomme immer noch die gleiche Warnung. Was gibt?

+5

Dies ist der beste Artikel, den ich zu diesem Thema gelesen habe: https://www.dataquest.io/blog/settingwithcopywarning/ Es ist auch hier in den Pandas docs angesprochen: http: //pandas.pydata .org/pandas-docs/stable/indexing.html? highlight = kette # indexing-view-versus-copy – Alexander

Antwort

12

Wenn complete = train.dropna() ausgeführt wird, dropna könnte eine Kopie zurückgeben, so aus einer Fülle von Vorsicht, setzt Pandas complete.is_copy auf einen truthy Wert:

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

Dies ermöglicht Pandas Sie später zu warnen, wenn complete['AgeGt15'] = complete['Age'] > 15 wird ausgeführt, dass Sie möglicherweise eine Kopie ändern, die keine Auswirkungen auf train hat. Für Anfänger kann dies eine nützliche Warnung sein. In Ihrem Fall scheint es, dass Sie nicht die Absicht haben, train indirekt zu modifizieren, indem Sie complete ändern. Daher ist die Warnung in Ihrem Fall nur ein bedeutungsloser Ärger.

Sie können die Warnung zum Schweigen von

complete.is_copy = False 

Einstellung Dies ist schneller als eine tatsächliche Kopie zu machen, und klemmt die SettingWithCopyWarning im Keim (an dem Punkt where _check_setitem_copy is called):

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

Wenn Sie wirklich sicher sind, dass Sie wissen, was Sie tun, können Sie die SettingWithCopyWarning global mit

abschalten
pd.options.mode.chained_assignment = None # None|'warn'|'raise' 
+1

Glaubst du, dass das konsistent ist? Es wird die gleiche Warnung mit "drop_duplicates" ausgelöst, aber nicht mit "drop". – ayhan

+2

@ayhan: Es gibt auch keine Warnung, wenn 'complete = complete.assign (AgeGt15 = (complete ['Age']> 15))' verwendet wird. Der Mechanismus, den Pandas verwendet, um "SettingWithCopyWarning" zu folgern, ist nicht narrensicher. Es fängt die häufigsten Fälle, aber nicht alle. – unutbu

+0

danke für den Trick 'is_copy' - ich wusste nicht, dass es existiert – MaxU