A value is trying to be set on a copy of a slice from a DataFrame

前言

我尝试给pandas中筛选后数据的某行某列赋值时,提示SettingWithCopyWarning:,是说不能直接对副本进行数据修改。

问题复现

原始数据

image.png

此处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']

处理后的结果:

image.png

总结(不想看前面废话请看这里:)

1,建议只使用一个loc或一个iloc方法赋值,即df.loc[xx]=zzdf.iloc[xx]=zz;不能同时使用loc和iloc赋值,即df.loc[xx].iloc[yy]=zz
2,如果想实现1中同时使用loc和iloc后进行赋值,可先用临时变量存loc的值,再对临时变量进行iloc的运算,处理后再赋值回原变量

你可能感兴趣的:(A value is trying to be set on a copy of a slice from a DataFrame)