SettingWithCopyWarning 解决方案

SettingWithCopyWarning 解决方案

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

一个简易版的范例

import pandas as pd
import numpy as np

aa = np.array([1, 0, 1, 0])
bb = pd.DataFrame(aa.T, columns=['one'])
bb['two'] = 0print(bb)

 
 
  • 1
  • 2
output[]:
   one  two
0    1    0
1    0    0
2    1    0
3    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] = 1
print(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 DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  bb['two'][i] = 1
   one  two
0    1    0
1    0    1
2    1    0
3    0    1
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这个问题怎么解决呢?

方法一:

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


方法二:

for i in range(bb.shape[0]):
    if bb['one'][i] == 0:
        bb.loc['one',i] = 1
print(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不可行?


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



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值