无法解释为何出现SettingWithCopyError(Python2.7,Pandas0.20.3)
解决Pandas的SettingWithCopyError问题
嘿,我太懂这个SettingWithCopyError的坑了!我当初第一次遇到的时候也盯着代码半天没搞明白——明明逻辑没问题,为啥偏要报错警告?
先给你拆解下问题出在哪:
你用results = df.loc[df['Message'].str.contains(search_string)]得到的results,大概率是原DataFrame的**视图(view)**而不是独立的副本(copy)。Pandas的这个设计是为了节省内存,但当你后续直接对results做列赋值(比如results.loc[:,'Duration'] = ...)时,它就会犯嘀咕:你到底是想修改原df的数据,还是只想修改这个切片出来的临时数据?因为不确定你的意图,所以就抛出了这个警告。
两种快速解决方法
方法1:直接生成副本(最直观推荐)
在获取results的时候,加上.copy()方法,把它变成完全独立的DataFrame,后续怎么修改都不会影响原df,也不会触发警告:
def filter_log(df, search_string): # 关键:加上.copy()生成独立副本 results = df.loc[df['Message'].str.contains(search_string)].copy() results.loc[:,'Duration'] = results.index.to_series().diff() results.loc[:,'Duration'] = results['Duration'].apply(lambda x: x.total_seconds()) results = results.dropna(subset=['Duration']) results['Day'] = results.index.floor('D') # 后续代码... return results
方法2:用链式assign操作(更简洁的写法)
如果你喜欢更紧凑的代码风格,可以用assign方法链式生成新的DataFrame,全程都是创建新对象,不会涉及视图修改的问题:
def filter_log(df, search_string): results = ( df.loc[df['Message'].str.contains(search_string)] .assign(Duration=lambda x: x.index.to_series().diff().apply(lambda y: y.total_seconds())) .dropna(subset=['Duration']) .assign(Day=lambda x: x.index.floor('D')) ) # 后续代码... return results
简单来说,核心就是让Pandas明确知道你操作的是一个独立的副本,而不是原数据的视图,这样它就不会再给你抛这个烦人的警告啦!
内容的提问来源于stack exchange,提问作者katamatsu
相关产品推荐
相关产品推荐

