gpt4 book ai didi

python - 通过计算传播 NaN

转载 作者:太空宇宙 更新时间:2023-11-03 12:50:33 26 4
gpt4 key购买 nike

通常,NaN(不是数字)通过计算传播,所以我不需要在每个步骤中检查 NaN。这几乎总是有效,但显然也有异常(exception)。例如:

>>> nan = float('nan')
>>> pow(nan, 0)
1.0

我找到了 following comment对此:

The propagation of quiet NaNs through arithmetic operations allows errors to be detected at the end of a sequence of operations without extensive testing during intermediate stages. However, note that depending on the language and the function, NaNs can silently be removed in expressions that would give a constant result for all other floating-point values e.g. NaN^0, which may be defined as 1, so in general a later test for a set INVALID flag is needed to detect all cases where NaNs are introduced.

To satisfy those wishing a more strict interpretation of how the power function should act, the 2008 standard defines two additional power functions; pown(x, n) where the exponent must be an integer, and powr(x, y) which returns a NaN whenever a parameter is a NaN or the exponentiation would give an indeterminate form.

有没有办法通过Python检查上面提到的INVALID标志?或者,有没有其他方法可以捕获 NaN 不传播的情况?

动机:我决定对缺失数据使用 NaN。在我的应用程序中,缺少输入应该会导致缺少结果。它工作得很好,除了我描述的异常(exception)。

最佳答案

我意识到这个问题已经过去一个月了,但我遇到了类似的问题(即 pow(float('nan'), 1) 在某些 Python 中抛出异常实现,例如 Jython 2.52b2),我发现上面的答案并不是我想要的。

使用 6502 建议的 MissingData 类型似乎是可行的方法,但我需要一个具体示例。我尝试了 Ethan Furman 的 NullType 类,但发现它不适用于任何算术运算,因为它不强制数据类型(见下文),而且我也不喜欢它显式命名每个被覆盖的算术函数。

从 Ethan 的示例和调整代码开始,我找到了 here ,我到了下面的类(class)。尽管该类有大量注释,但您可以看到它实际上只有几行功能代码。

关键点是:1. 使用 coerce() 为混合类型(例如 NoData + float)算术运算返回两个 NoData 对象,为基于字符串(例如 concat)的运算返回两个字符串。2. 使用 getattr() 为所有其他属性/方法访问返回一个可调用的 NoData() 对象3. 使用 call() 实现 NoData() 对象的所有其他方法:通过返回一个 NoData() 对象

下面是它的一些使用示例。

>>> nd = NoData()
>>> nd + 5
NoData()
>>> pow(nd, 1)
NoData()
>>> math.pow(NoData(), 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: nb_float should return float object
>>> nd > 5
NoData()
>>> if nd > 5:
... print "Yes"
... else:
... print "No"
...
No
>>> "The answer is " + nd
'The answer is NoData()'
>>> "The answer is %f" % (nd)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: float argument required, not instance
>>> "The answer is %s" % (nd)
'The answer is '
>>> nd.f = 5
>>> nd.f
NoData()
>>> nd.f()
NoData()

我注意到将 pow 与 NoData() 结合使用会调用 ** 运算符,因此可与 NoData 一起使用,但使用 math.pow 则不会,因为它首先尝试将 NoData() 对象转换为 float 。我很高兴使用非数学 pow - 希望 6502 等在他们在上面的评论中遇到 pow 问题时使用 math.pow。

另一个我想不出解决方法的问题是使用格式 (%f) 运算符......在这种情况下没有调用 NoData 的方法,如果你不提供,运算符就会失败一个花车。无论如何,这是类(class)本身。

class NoData():
"""NoData object - any interaction returns NoData()"""
def __str__(self):
#I want '' returned as it represents no data in my output (e.g. csv) files
return ''

def __unicode__(self):
return ''

def __repr__(self):
return 'NoData()'

def __coerce__(self, other_object):
if isinstance(other_object, str) or isinstance(other_object, unicode):
#Return string objects when coerced with another string object.
#This ensures that e.g. concatenation operations produce strings.
return repr(self), other_object
else:
#Otherwise return two NoData objects - these will then be passed to the appropriate
#operator method for NoData, which should then return a NoData object
return self, self

def __nonzero__(self):
#__nonzero__ is the operation that is called whenever, e.g. "if NoData:" occurs
#i.e. as all operations involving NoData return NoData, whenever a
#NoData object propagates to a test in branch statement.
return False

def __hash__(self):
#prevent NoData() from being used as a key for a dict or used in a set
raise TypeError("Unhashable type: " + self.repr())

def __setattr__(self, name, value):
#This is overridden to prevent any attributes from being created on NoData when e.g. "NoData().f = x" is called
return None

def __call__(self, *args, **kwargs):
#if a NoData object is called (i.e. used as a method), return a NoData object
return self

def __getattr__(self,name):
#For all other attribute accesses or method accesses, return a NoData object.
#Remember that the NoData object can be called (__call__), so if a method is called,
#a NoData object is first returned and then called. This works for operators,
#so e.g. NoData() + 5 will:
# - call NoData().__coerce__, which returns a (NoData, NoData) tuple
# - call __getattr__, which returns a NoData object
# - call the returned NoData object with args (self, NoData)
# - this call (i.e. __call__) returns a NoData object

#For attribute accesses NoData will be returned, and that's it.

#print name #(uncomment this line for debugging purposes i.e. to see that attribute was accessed/method was called)
return self

关于python - 通过计算传播 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10034455/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com