假设我有以下 pandas DataFrame:
df = pd.DataFrame({
'team': ['Warriors', 'Warriors', 'Warriors', 'Rockets', 'Rockets'],
'player': ['Stephen Curry', 'Klay Thompson', 'Kevin Durant', 'Chris Paul', 'James Harden']})
当我尝试在 team
列上分组并执行操作时,我得到一个 SettingWithCopyWarning
:
for team, team_df in df.groupby(by='team'):
# team_df = team_df.copy() # produces no warning
team_df['rank'] = 10 # produces warning
team_df.loc[:, 'rank'] = 10 # produces warning
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_index,col_indexer] = value instead
df_team['rank'] = 10
如果我取消注释生成子 DataFrame 副本的行,我不会收到错误。这通常是避免此警告的最佳做法,还是我做错了什么?
请注意,我不想编辑原始 DataFrame df
。我也知道这个例子可以用更好的方式完成,但我的用例要复杂得多,需要对原始 DataFrame 进行分组,并根据不同的 DataFrame 和该独特组的规范执行一系列操作。
最佳答案
一旦你理解了this article并且是
确信您知道如何避免链式索引(通过使用 .loc
或
iloc
) 然后你可以关闭 SettingWithCopyWarning
pd.options.mode.chained_assignment = None
再也不会被这个警告打扰了。
既然你写了
Note I don't want to edit the original DataFrame df
并且您正确地使用了 .loc
来分配给 team_df
,很明显您
已经知道修改副本(team_df
)不会修改原件
(df
),因此此处发出的 SettingWithCopyWarning
只是一个麻烦事。
SettingWithCopyWarning
会在您遇到的各种情况下出现
正确编码,即使使用 .loc
或 .iloc
。没有“正确”的编码方式
这避免了有时触发 SettingWithCopyWarning
s。
因此,我会在全局范围内关闭此警告
pd.options.mode.chained_assignment = None
我通常不推荐使用 team_df = team_df.copy()
只是为了避免
SettingWithCopyWarning
s -- 复制数据帧可能会耗尽资源
性能,尤其是当数据帧很大或在循环中完成多次时。
如果你想turn off the warning in just one location ,你可以使用
team_df.is_copy = False
它的目的相同,但不会消耗性能。但是请注意,
is_copy
官方 Pandas API 中没有提到,所以它可能不是
保证在所有 future 版本中存在或为此目的有用
Pandas 。因此,如果鲁棒性是优先考虑但性能不是那么可能使用
team_df = team_df.copy()
。但我认为对于有经验的人来说更合理的方式
Pandas 程序员要做的是全局关闭警告,或者——如果你
想要非常小心 - 保留警告,手动检查它们,但接受
它有时会被正确的代码触发。
关于python - pandas:使用 groupby yield SettingWithCopyWarning 的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45109257/