SettingWithCopyWarning 解决方案

来源:互联网 发布:淘宝网雪纺上衣 编辑:程序博客网 时间:2024/06/16 15:25

SettingWithCopyWarning 解决方案

问题场景:我在读取csv文件之后,因为要新增一个特征列并根据已有特征修改新增列的值,结果在修改的时候就碰到了SettingWithCopyWarning这个警告,花了很长时间才解决这个问题。

一个简易版的范例

import pandas as pdimport numpy as npaa = np.array([1, 0, 1, 0])bb = pd.DataFrame(aa.T, columns=['one'])bb['two'] = 0print(bb)
  • 1
  • 2
output[]:   one  two0    1    01    0    02    1    03    0    0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

按条件修改新列再输出就报错了:

for i in range(bb.shape[0]):    if bb['one'][i] == 0:        bb['two'][i] = 1print(bb)output[]:C:/PycharmProjects/NaiveBayesProduct/pandas/try_index.py:22: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrameSee the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy  bb['two'][i] = 1   one  two0    1    01    0    12    1    03    0    1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这个问题怎么解决呢?

方法一:

c = bb['one']==0bb.loc[c,'one']=1print(bb)
   one  two0    1    01    1    12    1    03    1    1
c的类型是series,为什么这种情况下,bb.loc就不再是副本了?这个问题我也没想清楚?如有网友清楚请告诉我 。


方法二:

for i in range(bb.shape[0]):    if bb['one'][i] == 0:        bb.loc['one',i] = 1print(bb)
或者

for i in range(bb.shape[0]):#    if bb.loc['one',i] == 0:  #KeyError: 'the label [one] is not in the [index]'#    if bb.loc[i,'one'] == 0:  #可行    if bb.loc[i]['one'] == 0:  # 可行        #bb.loc['one',i] = 1  #可行        bb.loc[i,'one'] = 1

试验了一下标着“可行“的都行,唯一一个疑惑是倒数第二行
bb.loc['one',i]=1可行,为什么第二行的bb.loc['one',i] == 0不可行?


最佳方法还是方法一,尤其适合在行数比较多,条件比较复杂的情况下。


 
原创粉丝点击