在列创建上设置WithCopyWarning

时间:2016-09-30 18:25:38

标签: python pandas

我正在尝试为我的数据创建一个名为' mv_avg'的移动平均列。我得到了一个我无法修复的SettingWithCopyWarning。我可以抑制警告,但我无法弄清楚我的代码在哪里创建副本,我想利用最佳实践。我在下面创建了一个可推广的示例来说明问题。

data = {'category' : ['a', 'a', 'a', 'b', 'b', 'b'], 'value' : [1,2,3,4,5,6]}
df = pd.DataFrame(data)
df_a = df.loc[df['category'] == 'a']
df_a['mv_avg'] = df_a['value'].rolling(window=2).mean()

返回:

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

我也尝试了更详细的版本:

df_a.loc[: , 'mv_avg'] = df_a.loc[:,'value'].rolling(window=2).mean()

但是我得到了同样的错误。在没有警告的情况下实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:5)

您可以使用.copy()

创建副本
import pandas as pd
data = {'category' : ['a', 'a', 'a', 'b', 'b', 'b'], 'value' : [1,2,3,4,5,6]}
df = pd.DataFrame(data)
df_a = df.loc[df['category'] == 'a'].copy()
df_a['mv_avg'] = df_a['value'].rolling(window=2).mean()

或者您可以使用索引器:

import pandas as pd
data = {'category' : ['a', 'a', 'a', 'b', 'b', 'b'], 'value' : [1,2,3,4,5,6]}
df = pd.DataFrame(data)
indexer = df[df['category'] == 'a'].index
df_a = df.loc[indexer, :]
df_a['mv_avg'] = df_a['value'].rolling(window=2).mean()

答案 1 :(得分:2)

以下是三个选项

  1. 忽略/过滤警告;在这种情况下,由于您故意分配过滤的DataFrame,因此它是虚假的。

  2. 如果您已完成df,则可del,这会阻止警告,因为df_a将不再保留对df的引用

  3. 按照其他答案

  4. 进行复制