我一直在四处寻找pandas docs here,并在here和here周围发布的问题中尝试不同的代码行,我似乎无法通过复制警告远离设置。我更愿意学习编码"对"方式而不仅仅是ignoring the warnings.
以下几行代码都在for循环中,我不想多次生成此警告,因为它可能会减慢速度。
我试图创建一个名为的新列:' E' + vs其中vs是for循环列表中的字符串
但是对于他们中的每一个,我仍然得到以下警告,即使是最后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')
答案 0 :(得分:3)
这是一个令人困惑的话题。您发布的代码不是问题所在。这是您尚未发布的代码。它是生成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
答案 1 :(得分:1)
首先,我不确定这是高效还是最佳方法。但是,当我向现有数据框添加新列时,我遇到了同样的问题,我决定使用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
这样我没有收到警告。希望有所帮助。