2

我一直在寻找阅读熊猫文档here并尝试从herehere发布的问题中使用不同的代码行,我似乎无法摆脱带有复制警告的设置。我更愿意学习以“正确”的方式对其进行编码,而不是仅仅忽略警告。

以下代码行位于 for 循环中,我不想多次生成此警告,因为它可能会减慢速度。

我正在尝试使用名称创建一个新列:'E'+vs where vs is a string in a list in for loop

但是对于它们中的每一个,我仍然收到以下警告,即使是最后 3 行:

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

以下是我迄今为止尝试过的麻烦线:

#based on research, the first two seem to be the "wrong" way

df_out['E'+vs] = df_out[kvs].rolling(v).mean().copy()
df_out['E'+vs] = df_out[kvs].rolling(v).mean()

df_out.loc[:,'E'+vs] = df_out[kvs].rolling(v).mean().copy()
df_out.loc[:,'E'+vs] = df_out[kvs].rolling(v).mean()
df_out.loc[:,'E'+vs] = df_out.loc[:,kvs].rolling(v).mean()

另一个给出 SettingWithCopyWarning 的是:

df_out.dropna(inplace=True,axis=0)

这个也发出了警告(但我认为这个会)

df_out = df_out.dropna(inplace=True,axis=0)

如何正确执行这两项操作?

编辑:这是产生原始 df_out 的代码

df_out= pd.concat([vol.Date[1:-1], ret.Return_Time[:-2], vol.Freq_Time[:-2],
               vol.Freq_Time[:-1].shift(-1), vol.Freq_Time[:].shift(-2)],
               axis=1).dropna().set_index('Date')
4

2 回答 2

6

这是一个令人困惑的话题。问题不是您发布的代码。这是您尚未发布的代码。这是生成的代码df_out

考虑此示例并注意生成警告的最后一行。

df_other = pd.DataFrame(dict(A=[1], B=[2]))
df_out = df_other[:]

df_out['E'] = 5
//anaconda/envs/3.5/lib/python3.5/site-packages/ipykernel/__main__.py:4: 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: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

现在我们将尝试一个不会产生警告的等效方法

df_other = pd.DataFrame(dict(A=[1], B=[2]))
df_out = df_other.loc[:]

df_out['E'] = 5

然后

print `df_out`

   A  B  E
0  1  2  5

它归结为熊猫决定在is_copy基于许多标准构建数据框时将属性附加到数据框。

注意

df_other[:].is_copy

<weakref at 0x103323458; to 'DataFrame' at 0x116a684e0>

什么时候

df_other.loc[:].is_copy

退货None


那么什么类型的构造会触发复制呢?我仍然不知道一切,甚至我所知道的事情对我来说都没有意义。

就像为什么这不会触发它?

df_other[['A', 'B', 'E']].is_copy
于 2017-04-02T07:15:13.460 回答
2

首先,我不确定这是有效还是最好的方法。但是,当我向现有数据框添加新列时遇到了同样的问题,我决定使用 reset_index 方法。

在这里,我首先从 EMPLOYEES 列中删除 Nan 行,并将这个操纵的数据框分配给新的数据框 df1,然后我将 COMPANY_SIZE 列添加到 df1,如下所示:

df1 = all_merged_years.dropna(subset=['EMPLOYEES']).reset_index()

column = df1['EMPLOYEES']

Size =[]

df1['COMPANY_SIZE'] = ' '

for number in column:
    if number <=999:
        Size.append('Small')
    elif 999<number<=9999:
        Size.append('Medium')
    elif 9999<number:
        Size.append('Large')
    else:
        Size.append('UNKNOWN')

df1['COMPANY_SIZE'] = Size

这样我就没有收到这样的警告。希望有帮助。

于 2018-04-18T14:27:55.757 回答