NumPy中包含无限大复数的平均值

8

numpy似乎并不善于处理复杂无穷大。

虽然我们可以评估:

In[2]: import numpy as np

In[3]: np.mean([1, 2, np.inf])
Out[3]: inf

以下结果更加繁琐:
In[4]: np.mean([1 + 0j, 2 + 0j, np.inf + 0j])
Out[4]: (inf+nan*j)
...\_methods.py:80: RuntimeWarning: invalid value encountered in cdouble_scalars
  ret = ret.dtype.type(ret / rcount)

我不确定虚部对我来说是否有意义。但如果我错了,请评论。

在numpy中处理复数无穷大的任何见解?


1
可能是[复杂无穷大 - 奇怪的结果 - 一个 numpy bug?]的重复问题(https://dev59.com/b5nga4cB1Zd3GeqPaZGn) - Cong Ma
3个回答

5

解决方案

计算平均值时,我们需要将总和除以一个实数。但由于类型提升的原因(见下文),这种除法会导致问题。为避免类型提升,我们可以手动分别计算总和的实部和虚部的商:

n = 3
s = np.sum([1 + 0j, 2 + 0j, np.inf + 0j])
mean = np.real(s) / n + 1j * np.imag(s) / n
print(mean)  # (inf+0j)

背景

这个问题与numpy无关,而是与复数除法的执行方式有关。请注意,((1 + 0j) + (2 + 0j) + (np.inf + 0j)) / (3+0j) 的结果也是 (inf+nanj)

结果需要分成实部和虚部。对于除法来说,两个操作数都被提升为复数,即使你除以一个实数。所以基本上除法是这样的:

 a + bj
--------
 c + dj

除法运算并不知道 d=0。因此,为了将结果分成实数和虚数部分,必须消去分母中的 j。这是通过用复共轭乘以分子和分母来完成的:
 a + bj     (a + bj) * (c - dj)     ac + bd + bcj - adj
-------- = --------------------- = ---------------------
 c + dj     (c + dj) * (c - dj)        c**2 + d**2

现在,如果a=infd=0,那么项a * d * j = inf * 0 * j = nan * j

4
当你在数组中使用 np.inf 运行函数时,结果将会是无限大的对象,例如 np.mean 或其他类似于 np.max() 的函数。但是,在计算 mean() 时,由于你有复数,而一个无限大的复数被定义为“在复平面上其复参数未知或未定义的无限大数”,你将得到非零虚部 non*j
为了解决这个问题,你应该忽略这些无限大的项。你可以使用 isfinite() 函数检测它们并将该函数应用于有限项:
In [16]: arr = np.array([1 + 0j, 2 + 0j, np.inf + 0j])

In [17]: arr[np.isfinite(arr)]
Out[17]: array([ 1.+0.j,  2.+0.j])

In [18]: np.mean(arr[np.isfinite(arr)])
Out[18]: (1.5+0j)

0

由于类型提升的原因。

当你对一个复数除以一个实数,比如 (inf + 0j) / 2,这个(实数)被提升为 2 + 0j

通过复数除法,虚部等于 (0 * 2 - inf * 0) / 4。注意这里的 inf * 0 是一个不定形式,它的值为 NaN。这使得虚部变成了 NaN

回到主题。当 numpy 计算一个复数数组的平均值时,它并没有尝试做任何聪明的事情。首先,它使用“加法”操作来减少数组,得到总和。之后,将总和除以计数。这个总和包含一个实部为 inf 的值,当除数(计数)从整数类型提升为复杂浮点数时,就会出现上述问题。

编辑:关于解决方案的说明

IEEE浮点数中的“无穷大”实际上是一种非常原始的构造,表示不定形式,例如1 / 0。这些形式不是常数,而是可能的极限。特殊的infNaN“浮点数”是占位符,通知您存在不定形式。它们对极限的存在或类型没有任何作用,您必须通过数学上下文来确定。

即使对于实数,基础极限也可能取决于您如何接近极限。表面上的1 / 0形式可以趋向正无穷大或负无穷大。在复平面上,情况甚至更加复杂(好吧)。例如,您可能会遇到分支切割和(不同类型的)奇点。没有适用于所有情况的通用解决方案。

Tl;dr:在面对模糊/不完整/损坏的数据时修复基础问题,或证明最终计算结果可以承受这种损坏(可能会发生)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接