2016-08-07 18 views
6

Lúc đầu, tôi đã cố gắng viết một số mã mà trông như thế này:Pandas vẫn nhận được SettingWithCopyWarning ngay cả sau khi sử dụng .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 

Sau khi nhận được SettingWithCopyWarning, tôi đã cố gắng using.loc:

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

Tuy nhiên , Tôi vẫn nhận được cảnh báo tương tự. Đưa cái gì?

+5

Đây là bài viết hay nhất tôi đã đọc về chủ đề này: https://www.dataquest.io/blog/settingwithcopywarning/ Nó cũng được đề cập trong tài liệu Pandas tại đây: http: //pandas.pydata .org/pandas-docs/stable/indexing.html? highlight = chain # indexing-view-versus-copy – Alexander

Trả lời

12

Khi complete = train.dropna() được thực thi, dropna có thể trả về một bản sao, vì vậy ra khỏi một sự phong phú của cách thận trọng, Pandas đặt complete.is_copy đến một giá trị Truthy :

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

này cho phép Pandas để cảnh báo bạn sau, khi complete['AgeGt15'] = complete['Age'] > 15 được thực hiện mà bạn có thể sửa đổi một bản sao sẽ không có hiệu lực trên train. Đối với người mới bắt đầu, đây có thể là một cảnh báo hữu ích. Trong trường hợp của bạn, có vẻ như bạn không có ý định sửa đổi train gián tiếp bằng cách sửa đổi complete. Do đó cảnh báo chỉ là một sự phiền toái vô nghĩa trong trường hợp của bạn.

Bạn có thể tắt cảnh báo bằng cách thiết lập

complete.is_copy = False 

này nhanh hơn làm cho một bản sao thực tế, và tách SettingWithCopyWarning từ trong trứng nước (tại điểm where _check_setitem_copy is called):

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

Nếu bạn thực sự tự tin mình biết mình đang làm gì, bạn có thể tắt SettingWithCopyWarning trên toàn cầu với

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

Bạn có nghĩ điều này là nhất quán không? Nó tăng cùng cảnh báo với 'drop_duplicates' nhưng không phải với' drop'. – ayhan

+2

@ayhan: Cũng không có cảnh báo nếu 'complete = complete.assign (AgeGt15 = (hoàn thành ['Age']> 15))' được sử dụng. Cơ chế Pandas sử dụng để suy ra 'SettingWithCopyWarning' không phải là giả mạo. Nó bắt các trường hợp phổ biến nhất, nhưng không phải tất cả. – unutbu

+0

cảm ơn bạn vì mẹo 'is_copy' - tôi không biết nó tồn tại – MaxU

Các vấn đề liên quan