我刚把我的熊猫从0.11升级到0.13.0rc1。现在,应用程序弹出了许多新的警告。其中一个是这样的:
E:\FinReporter\FM_EXT.py:449: 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
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
我想知道这到底是什么意思?我需要改变什么吗?
如果我坚持使用quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
,应该如何暂停警告?
def _decode_stock_quote(list_of_150_stk_str):
"""decode the webpage and return dataframe"""
from cStringIO import StringIO
str_of_all = "".join(list_of_150_stk_str)
quote_df = pd.read_csv(StringIO(str_of_all), sep=',', names=list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg')) #dtype={'A': object, 'B': object, 'C': np.float64}
quote_df.rename(columns={'A':'STK', 'B':'TOpen', 'C':'TPCLOSE', 'D':'TPrice', 'E':'THigh', 'F':'TLow', 'I':'TVol', 'J':'TAmt', 'e':'TDate', 'f':'TTime'}, inplace=True)
quote_df = quote_df.ix[:,[0,3,2,1,4,5,8,9,30,31]]
quote_df['TClose'] = quote_df['TPrice']
quote_df['RT'] = 100 * (quote_df['TPrice']/quote_df['TPCLOSE'] - 1)
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
quote_df['TAmt'] = quote_df['TAmt']/TAMT_SCALE
quote_df['STK_ID'] = quote_df['STK'].str.slice(13,19)
quote_df['STK_Name'] = quote_df['STK'].str.slice(21,30)#.decode('gb2312')
quote_df['TDate'] = quote_df.TDate.map(lambda x: x[0:4]+x[5:7]+x[8:10])
return quote_df
E:\FinReporter\FM_EXT.py:449: 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
quote_df['TVol'] = quote_df['TVol']/TVOL_SCALE
E:\FinReporter\FM_EXT.py:450: 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
quote_df['TAmt'] = quote_df['TAmt']/TAMT_SCALE
E:\FinReporter\FM_EXT.py:453: 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
quote_df['TDate'] = quote_df.TDate.map(lambda x: x[0:4]+x[5:7]+x[8:10])
一般来说,
SettingWithCopyWarning
的目的是向用户(尤其是新用户)表明,他们可能在拷贝上操作,而不是他们认为的原始操作。有是假阳性(如果你知道你在做什么,可能是好的)。一种可能是按照@Garrett的建议关闭(默认情况下warn)警告。还有一个选择:
您可以将
is_copy
标志设置为False
,这将有效地关闭该对象的检查,:如果显式复制,则不会出现进一步警告:
上面这个操作显示的代码虽然是合法的,而且可能我也做了些什么,但从技术上来说,它是这个警告的一个例子,而不是一个误报。另一种不发出警告的方法是通过
reindex
进行选择操作,例如或者
创建
SettingWithCopyWarning
是为了标记可能混淆的“链式”赋值,例如以下赋值,这些赋值并不总是按预期工作,特别是当第一个选择返回copy时。[背景讨论见GH5390和GH5597。]警告建议重写如下:
但是,这不适合您的使用,相当于:
虽然很明显,您不关心写操作使其回到原始帧(因为您重写了对它的引用),但不幸的是,此模式无法与第一个链式赋值示例区分开来,因此出现(误报)警告。如果您想进一步阅读,那么docs on indexing中说明了误报的可能性。您可以通过以下分配安全地禁用此新警告。
这篇文章是为读者准备的
设置
什么是
SettingWithCopyWarning
?要知道如何处理这一警告,首先必须了解它的含义和提出原因。
过滤数据帧时,根据内部布局和各种实现细节,可以对帧进行切片/索引,以返回视图或副本。顾名思义,“视图”是原始数据的视图,因此修改视图可能会修改原始对象。另一方面,“拷贝”是原始数据的复制,修改拷贝对原始数据没有影响。
正如其他答案所提到的,创建
SettingWithCopyWarning
是为了标记“链式赋值”操作。考虑上面设置中的df
。假设要选择“B”列中的所有值,其中“A”列中的值为5。熊猫允许你用不同的方式来做这件事,有些比其他更正确。例如而且
它们返回相同的结果,因此如果您只读取这些值,则没有区别。那么,问题是什么?链式赋值的问题是,通常很难预测是否返回视图或副本,因此,当您试图重新赋值时,这在很大程度上成为一个问题。要在前面的示例的基础上构建,请考虑解释器如何执行此代码:
用一个
__setitem__
调用df
。哦,考虑一下这个代码:现在,根据
__getitem__
返回的是视图还是副本,__setitem__
操作可能不起作用。一般来说,应该使用^{} 作为基于标签的赋值,使用^{} 作为基于整数/位置的赋值,因为规范保证它们始终在原始值上操作。另外,对于设置单个单元格,应该使用^{} 和^{} 。
更多信息可以在documentation中找到。
告诉我怎么抑制警告!
考虑对
df
的“a”列执行一个简单的操作。选择“A”并除以2将发出警告,但操作将起作用。有几种方法可以直接消除此警告:
制作一个
deepcopy
更改
pd.options.mode.chained_assignment
可以设置为
None
、"warn"
,或"raise"
。"warn"
是默认值。None
将完全抑制警告,并且"raise"
将抛出一个SettingWithCopyError
,阻止操作进行。在注释中,@Peter Cotton提出了一种使用上下文管理器非侵入性地更改模式(从this gist修改)的好方法,仅在需要时设置模式,并在完成后将其重置回原始状态。
用法如下:
或者,提出例外
“XY问题”:我做错了什么?
很多时候,用户试图寻找抑制这种异常的方法,而不完全理解为什么首先会出现这种异常。这是XY problem的一个很好的例子,用户试图解决一个问题“Y”,这实际上是一个根深蒂固的问题“X”的症状。将根据遇到此警告的常见问题提出问题,然后提出解决方案。
错误的方法:
正确使用
loc
:您可以使用以下任何方法来执行此操作。
这实际上可能是因为在你的管道中有更高的代码。你是不是用更大的东西,比如
是吗?在这种情况下,布尔索引将返回一个视图,因此
df2
将引用原始视图。您需要做的是将df2
分配给副本:这是因为
df2
必须是从其他切片操作(如这里的解决方案是将
copy()
变成df
,或者像以前一样使用loc
。相关问题 更多 >
编程相关推荐