前言
我尝试给pandas中筛选后数据的某行某列赋值时,提示SettingWithCopyWarning:
,是说不能直接对副本进行数据修改。
问题复现
原始数据
此处
year-month-day
为签到日期,diff
是我想计算的连续签到天数,如果下一行减去本行为1,则计为连续签到天数,diff
的值+1。
我原来的赋值方法:
df.loc[df['user_id'] == i,'diff'].iloc[j] = 1# 报错,其中i为第i个user_id的值,j为同一user_id的第j行
这里我通过df.loc[df[xx]==i,'yy'].iloc[j] = zz
赋值(xx、yy均为列名),其中df.loc[df[xx]==i]
后直接赋值是可以的,df.loc[df[xx]==i]
为df的一个子集,即view或视图,而df.loc[df[xx]==i,'yy'].iloc[j]
为df的一个副本,是不能直接赋值的(但是可以print查看)。
处理方法(供参考,不适用所有场景)
我的处理方法比较傻:先把df.loc[df[xx]==i].copy()
赋给一个临时变量dfx
,然后dfx.iloc[j,dfx.columns.get_loc('yy')] = zz
计算完后再把临时变量赋值回原df,即df.loc[df[xx]==i,'yy'] = dfx['yy']
。
处理后的结果:
总结(不想看前面废话请看这里:)
1,建议只使用一个loc或一个iloc方法赋值,即df.loc[xx]=zz
或df.iloc[xx]=zz
;不能同时使用loc和iloc赋值,即df.loc[xx].iloc[yy]=zz
。
2,如果想实现1中同时使用loc和iloc后进行赋值,可先用临时变量存loc的值,再对临时变量进行iloc的运算,处理后再赋值回原变量