pandas:使用groupby的操作产生SettingWithCopyWarning

时间:2017-07-14 18:07:27

标签: python pandas

假设我有以下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和该唯一组的规范执行一系列操作。

2 个答案:

答案 0 :(得分:6)

一旦你找到this article并且是 自信你知道如何避免链式索引(通过使用.lociloc)然后您可以关闭SettingWithCopyWarning pd.options.mode.chained_assignment = None再也不会被这个警告所困扰。

自从你写了

  

注意我不想编辑原始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

它有同样的目的,但不会造成性能损失。但请注意, 官方Pandas API中未提及is_copy,因此可能不会 保证在将来的所有版本中都存在或对此有用 大熊猫。因此,如果稳健性是一个优先事项,但性能不是那么可能使用 team_df = team_df.copy()。但我觉得有经验的方法更健全 Pandas程序员要么全局关闭警告,要么 - 如果你 想要非常小心 - 保留警告,手动检查,但接受 它有时会被正确的代码触发。

答案 1 :(得分:0)

pandas split apply combine docs并不是很好。这应该指向正确的方向

def apply_fun(team_df):
    team_df['rank'] = 10
    return team_df

df.groupby('team').apply(apply_fun)
df['column_rank'] = df.groupby('team')['column'].transform(lambda x: x.rank())