在使用pandas的.sort_values时出现SettingWithCopyWarning警告。

14
我正在尝试按总列对数据框进行排序。
df.sort_values(by='Total', ascending=False, axis=0, inplace=True)

但是我收到了以下警告:
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  """Entry point for launching an IPython kernel.

当我点击链接并使用.loc方法时,建议使用。但在那之后,我按照.sort_values()的方式进行了操作,发现需要使用inplace=False或None。
我的问题是,如果我有一个未排序的数据框列,如果我不使用inplace=True,那么我的数据框是否会被排序以供进一步使用,还是我必须为数据框分配一个新名称并保存它。

4
我有完全相同的问题,我认为inplace=True不应该这样做,但我是个新手,所以我不敢说它是一个错误,只是在我看来像是一个错误。我去掉了inplace并代替将数据框赋值给变量,一切都正常了。在你提供的链接中,inplace支持True。 - Julian Moore
2
@JulianMoore 同意。在我看来,这是一个错误。 - jlplenio
这个错误很可能是由于在排序之前的代码中,你将df设置为df的副本。一个常见的例子是 df = df[['columnA', 'columnB']]。如果你分享一下之前的代码行,我很乐意帮助你找到解决方案。 - Scott Guthart
3个回答

6
警告信息不够清晰,但如果你在通过过滤另一个数据框创建数据框时使用.copy()和.loc组合,则该警告应该消失。
import pandas as pd

df = pd.DataFrame({'num':range(10),'Total':range(20,30)})
# loc without copy
df_2 = df.loc[df.num <5]

df_2.sort_values(by='Total', ascending=False, axis=0, inplace =True)
# leads to SettingWithCopyWarning

df_3 = df.loc[df.num <5].copy()
df_3.sort_values(by='Total', ascending=False, axis=0, inplace =True)
# no warning

您可以在这里找到更多细节,但是有一类非常烦人的Pandas错误,设置带有复制警告的功能旨在保护您免受此类错误的影响。

df_4 = df.copy()
df_4['new_col'] = df_4.num *2
df_5 = df
df_5['new_col_2'] = df_5.num *3 

# df_5's column is also added to df, but not df_4, because of .copy()
df.columns
#Index(['num', 'Total', 'new_col_2'], dtype='object')

df[df.num <2].loc[:,['Total']] = 100
df.Total.max()
# still 29, because of the chained .locs, Total was not updated.
df.loc[df.num<2,'Total'] = 100
df.Total.max()
# 100

2

使用赋值(而不是原地操作)对我来说清除了警告:

df = df.sort_values(by='Total', ascending=False, axis=0)

1
我会避免原地操作,而是将排序后的数据框存储为这样的形式:
df_cp = df.copy() # optional copy of the original df
df_sort = df_cp.sort_values(by='Total', ascending=False, axis=0)
del df #deleting df if it's not needed

我遇到了一些看起来像是错误的复制警告,所以目前我更喜欢避免可能引发这些警告的语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接