一、复现:
import pandas as pd #读取2018年温度记录表 df=pd.read_csv('./beijing_tianqi/beijing_tianqi_2018.csv') #去掉最低温和最高温的°C df.loc[:,'bWendu']=df['bWendu'].str.replace('℃','').astype('int32') df.loc[:,'yWendu']=df['yWendu'].str.replace('℃','').astype('int32') #统计3月份的温差 #先将3月份筛选出来 condition=df['ymd'].str.startswith('2018-03') #计算三月份每天的温差 df[condition]['wen_cha']=df['bWendu']-df['yWendu'] #以下是报警 ''' C:\Users\Administrator\AppData\Local\Temp\ipykernel_6664\3066492218.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df[condition]['wen_cha']=df['bWendu']-df['yWendu'] '''
二、报警原因
df[condition]['wen_cha']=df['bWendu']-df['yWendu'],相当于df.get(condition).set('wen_cha'),是个链式操作。是第一步get发出了报警。
对于链式操作,先get后set,get到的dataframe可能是view,也可能是copy。view是子视图,对他的操作影响源dataframe。
总之,pandas不允许先筛选子dataframe再进行修改写入。
要么一步直接修改源
要么复制一个子dataframe后再修改
三、解决方案
对于pandas的dataframe的修改操作,只允许在源上进行,一步到位
#方法1:将2步操做改为1步操作 df.loc[condition,'wen_cha']=df['bWendu']-df['yWendu'] ''' ymd bWendu yWendu tianqi fengxiang fengli aqi aqiInfo aqiLevel wen_cha 59 2018-03-01 8 -3 多云 西南风 1-2级 46 优 1 11.0 60 2018-03-02 9 -1 晴~多云 北风 1-2级 95 良 2 10.0 61 2018-03-03 13 3 多云~阴 北风 1-2级 214 重度污染 5 10.0 62 2018-03-04 7 -2 阴~多云 东南风 1-2级 144 轻度污染 3 9.0 63 2018-03-05 8 -3 晴 南风 1-2级 94 良 2 11.0 '''
#方法2:使用copy方法,copy一个3月份的副本 df_month3=df[condition].copy() #特别注意copy要加(),否则df_month3是个method,不是dataframe df_month3['wen_cha']=df['bWendu']-df['yWendu'] df_month3.head() ''' ymd bWendu yWendu tianqi fengxiang fengli aqi aqiInfo aqiLevel wen_cha 59 2018-03-01 8 -3 多云 西南风 1-2级 46 优 1 11 60 2018-03-02 9 -1 晴~多云 北风 1-2级 95 良 2 10 61 2018-03-03 13 3 多云~阴 北风 1-2级 214 重度污染 5 10 62 2018-03-04 7 -2 阴~多云 东南风 1-2级 144 轻度污染 3 9 63 2018-03-05 8 -3 晴 南风 1-2级 94 良 2 11 '''