为啥我从熊猫那里得到 SettingWithCopyWarning
Posted
技术标签:
【中文标题】为啥我从熊猫那里得到 SettingWithCopyWarning【英文标题】:why am I getting SettingWithCopyWarning from pandas为什么我从熊猫那里得到 SettingWithCopyWarning 【发布时间】:2020-12-02 07:15:20 【问题描述】:我遇到了一些关于这个警告的问题,但仍然有点困惑。我的方法如下:
def _apply_standard_filters(self, df: pd.DataFrame) -> pd.DataFrame:
logger.info("Applying standard filters")
df["Type"] = df["Type"].apply(lambda x: x.strip().lower())
df = df[df.Type == "xxxx"]
df = df[df['Other Column'].str.contains(r"some_regex", na=False, regex=True)]
return df
我收到了关于带有 lambda 函数的那条行的警告。最初,当线条如下所示时,我收到了警告:
df["Type"] = df["Type"].str.strip()
df["Type"] = df["Type"].str.lower()
我认为这可能与分配两次相同的列有关,所以我重写以使用 apply(如在第一个 sn-p 中)。仍然收到相同的警告。最后我又用 loc 重写了一遍,像这样:
df["Type"] = df.loc[:, "Type"].apply(lambda x: x.strip().lower())
并且警告仍然存在。我在这里错过了什么?
这也是我得到的输出
2020-08-12 15:38:14,498 - filters - INFO - Applying standard filters
filters.py:16: 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["Type"] = df.loc[:, "Type"].apply(lambda x: x.strip().lower())
也许是关于我在调用该方法之前所做的事情?在我根据用户的选择使用其他过滤方法之后,我总是使用这个 _apply_standard_filters() 。但是,我从不在标准过滤器之前触摸类型或其他列。通常它看起来像这样:
df = df[df.Column1.str.contains(r"some other regex pattern", na=False, regex=True)]
df = self._apply_standard_filters(df=df)
欢迎提出任何建议。
干杯!
编辑
在@r.ook 回答后,我应用了他的解决方案,只是稍微修复了一点,但在我面前仍然有同样的警告。现在代码如下所示:
def _apply_standard_filters(self, df: pd.DataFrame) -> pd.DataFrame:
logger.info("Applying standard filters")
df["Type"] = df.loc[:, "Type"].apply(lambda x: x.strip().lower())
df = df.loc[df.Type == "xxxx"]
df = df.loc[df['Other Column'].str.contains(r"some_regex", na=False, regex=True)]
df = df[df['Other Column'].str.contains(r"some_regex", na=False, regex=True)]
return df
def filter_something(self, df: pd.DataFrame) -> pd.DataFrame:
df = df.loc[df.Column1.str.contains(r"^Some regex", na=False, regex=True)]
df = self._apply_standard_filters(df=df)
return df
当我运行它时,我仍然得到:
filters.py:17: 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: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df["Type"] = df.loc[:, "Type"].apply(lambda x: x.strip().lower())
我应该关注警告中提到的这一特定行吗?我以前没见过这个警告。它出现在我将strip()
和lower()
添加到df["Type"]
时。当我在没有该行的情况下运行代码时,无论我在其他 df 分配中所做的更改如何,都没有警告。
【问题讨论】:
【参考方案1】:只要你有类似df = df[...]
的行,它就会触发SettingWithCopyWarning
。
从您的最后一个问题来看,您似乎已经将副本传递给该方法,这就是触发警告的原因。
改为这样做:
df = df.loc[:, df.Column1.str.contains(r"some other regex pattern", na=False, regex=True)]
df = self._apply_standard_filters(df=df)
同样,编辑方法中遵循相同df = df[...]
模式的所有行:
df = df.loc[:, df.Type == "xxxx"]
df = df.loc[:, df['Other Column'].str.contains(r"some_regex", na=False, regex=True)]
【讨论】:
不可能在 cmets 中换行,所以 :) 上面不起作用,它会生成作为索引器提供的不可对齐的布尔系列(布尔系列的索引和索引对象的索引不匹配)。它应该看起来更像 df.loc[ df.Type == "vuln" ] 但是,我之前在这个脚本中没有遇到过原始警告。而且我总是使用 df = df[...] 模式 我的意思是,当你有df = df[...]
模式时,它不会立即 触发警告,而是任何后续分配/更改df
将触发警告。
我摆脱了这种模式df = df[...]
当它存在时仍然收到警告df["Type"] = df.loc[:, "Type"].apply(lambda x: x.strip().lower())
。如果我删除该行,即使我在其他行中返回 df = df[...]
模式,也不会发出警告以上是关于为啥我从熊猫那里得到 SettingWithCopyWarning的主要内容,如果未能解决你的问题,请参考以下文章
vbscript 第2部分我从安德鲁那里得到的代码是进出excel和/或进出的代码
vbscript 第2部分我从安德鲁那里得到的代码是进出excel和/或进出的代码