2014-11-03 14 views
19

Python 3.4 và Pandas 0.15.0Thiết lập PandasWithCopyWarning

df là một khung dữ liệu và col1 là một cột. Với mã bên dưới, tôi đang kiểm tra sự hiện diện của giá trị 10 và thay thế các giá trị đó bằng 1000.

df.col1[df.col1 == 10] = 1000 

Đây là một ví dụ khác. Lần này, tôi đang thay đổi giá trị trong col2 dựa trên chỉ mục.

df.col2[df.index == 151] = 500 

Cả hai tạo ra cảnh báo dưới đây:

-c:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame 

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 

Cuối cùng,

cols = ['col1', 'col2', 'col3'] 
df[cols] = df[cols].applymap(some_function) 

này tạo ra một cảnh báo tương tự, với một gợi ý thêm:

Try using .loc[row_indexer,col_indexer] = value instead 

tôi m không chắc tôi hiểu đĩa ussion chỉ vào trong các cảnh báo. Điều gì sẽ là một cách tốt hơn để viết ba dòng mã này?

Lưu ý rằng các thao tác đã hoạt động.

Trả lời

38

Vấn đề ở đây là: df.col1[df.col1 == 10] trả về một bản sao.

Vì vậy, tôi sẽ nói:

row_index = df.col1 == 10 
# then with the form .loc[row_indexer,col_indexer] 
df.loc[row_index, 'col1'] = 100 
+0

Cảm ơn. Nên là df.loc [row_index, 'col1'] = 100, phải không? –

+1

@ asif.m là tất nhiên chính xác 100%. Tôi sẽ sửa chữa nó –

+0

Bạn đề nghị tôi làm gì cho ví dụ thứ ba (với "áp dụng")? –

5

Đồng ý với Paul về việc sử dụng 'loc'.

Đối với trường hợp applymap của bạn, bạn sẽ có thể làm điều này:

cols = ['col1', 'col2', 'col3'] 
df.loc[:, cols] = df[cols].applymap(some_function) 
+3

Điều đó đưa ra cùng cảnh báo. Nhưng điều này không: df.loc [:, cols] = df.loc [:, cols] .applymap (some_function) –

+0

Thú vị. Tôi đang sử dụng gấu trúc 0.15.0 nhưng Python 2.7.5 nên không thử nghiệm với môi trường của bạn. Đề nghị của tôi không ném cảnh báo cho tôi. Tốt để biết rằng nỗ lực thứ hai của bạn đã làm việc – koelemay