提问人:TransitoryGouda 提问时间:6/16/2023 最后编辑:mkrieger1TransitoryGouda 更新时间:9/11/2023 访问量:34
如何更正此代码以不引发 SettingWithCopyWarning?
How to correct this code to not raise a SettingWithCopyWarning?
问:
我正在关注这个:https://www.kdnuggets.com/2021/01/cleaner-data-analysis-pandas-pipes.html
大约在一半的时候,作者创建了一个函数来删除异常值:
def to_category(df):
cols = df.select_dtypes(include='object').columns
for col in cols:
ratio = len(df[col].value_counts()) / len(df)
if ratio < 0.05:
df[col] = df[col].astype('category')
return df
这引起了 Python 的警告:
Warning (from warnings module):
File "D:/I7_Education/pandas_pipe_function1/pipes3.py", line 51
df[col] = df[col].astype('category')
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
我不确定我是否理解问题所在(尽管我正在努力解决它,并且在网上发布了一些帖子以试图理解)。我仍在尝试理解文档解释。
我知道我可以禁止来自 Python 的警告(如果您禁止警告,代码运行良好)。我想知道如何更改文章中的代码,以便它首先不会发出警告。
我尝试联系作者,但没有收到回复。
我想要的是没有必要压制。但是我不明白问题是什么,以至于无法弄清楚如何更改代码以首先不触发 SettingWithCopyWarning。
我没想到会发出警告。文档以及一些在线帖子说使用 loc 更改 df,但我不是在数据帧中更改值或元素,而是将列的 dtype 从对象更改为类别; 是如何做到这一点的,我认为遍历列来做到这一点应该没问题。一个朋友告诉我创建一个传递给函数的 df 副本,然后操作它,然后返回副本,我也不完全理解,但它并没有解决问题 - 它仍然会引发相同的警告。astype('catagory')
我传递给函数的数据帧是一个副本。本文只是在操作数据集(directmarketing.csv);它将 CSV 读取到 Pandas DataFrame 中并直接对其进行操作。相反,我创建了两个数据帧:第一个是,第二个是,我只是在操作营销数据帧。这样,我就可以回过头来检查数据集数据帧,并确保事情已经按照预期的方式发生了变化,等等。dataset = pd.read_csv(".\directmarketing.csv")
marketing = dataset.copy()
但是当我调用该函数时,我正在调用 - 我根本没有接触数据集数据帧。to_category(marketing)
stackoverflow 上有一个线程 - 使用 Python pandas 数据帧时返回副本与视图警告 - 谈到了这一点,但它说要制作副本以避免警告,所以我非常困惑。
有没有办法更正文章中的代码,使其不会触发此警告?
我正在使用 Python 3.10 和 Idle - 我没有使用 IDE。
答:
一个想法是通过 DataFrame.astype
重写解决方案,列表中的列名通过以下方式转换为字典:final
dict.fromkeys
def to_category(df):
final = []
cols = df.select_dtypes(include='object').columns
for col in cols:
ratio = len(df[col].value_counts()) / len(df)
if ratio < 0.05:
final.append(col)
return df.astype(dict.fromkeys(final, 'category'))
评论
dict.fromkeys(final, 'category')
category
final
return df.astype(dict.fromkeys(final, 'category'))
评论
loc
len(df[col].value_counts()) / len(df)
(~df[col].duplicated()).mean()
loc