当前位置: 首页 > 面试题库 >

添加零时奇怪的numpy.sum行为

龚奕
2023-03-14
问题内容

我了解由于数值误差(例如,以不同顺序对浮点求和),在数学上等效的算术运算如何导致不同的结果。

但是,令我惊讶的是,将零加到sum可以更改结果。我认为无论哪种情况,这对于浮动广告始终有效x + 0. == x

这是一个例子。我希望所有行都完全为零。有人可以解释为什么会这样吗?

M = 4  # number of random values
Z = 4  # number of additional zeros
for i in range(20):
    a = np.random.rand(M)
    b = np.zeros(M+Z)
    b[:M] = a
    print a.sum() - b.sum()

-4.4408920985e-16
0.0
0.0
0.0
4.4408920985e-16
0.0
-4.4408920985e-16
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
2.22044604925e-16
0.0
4.4408920985e-16
4.4408920985e-16
0.0

M和的较小值似乎不会发生Z。

我也确定a.dtype==b.dtype

这是另一个示例,它还演示了python的内置sum行为符合预期:

a = np.array([0.1,      1.0/3,      1.0/7,      1.0/13, 1.0/23])
b = np.array([0.1, 0.0, 1.0/3, 0.0, 1.0/7, 0.0, 1.0/13, 1.0/23])
print a.sum() - b.sum()
=> -1.11022302463e-16
print sum(a) - sum(b)
=> 0.0

我正在使用numpy V1.9.2。


问题答案:

简短的答案:您看到了两者之间的区别

a + b + c + d

(a + b) + (c + d)

由于浮点数的不准确性而不同。

长答案: Numpy实现了成对求和,以优化速度(它使矢量化更容易)和舍入误差。

numpy sum-implementation可以在这里找到(函数pairwise_sum_@TYPE@)。它基本上执行以下操作:

如果数组的长度小于8,则执行常规的for-loop求和。这就是为什么W < 4在您的情况下不会观察到奇怪结果的原因-两种情况下都将使用相同的for循环求和。
如果长度在8到128之间,则会将总和累加到8个bin中,r[0]-r[7]然后将它们相加((r[0] + r[1]) + (r[2] + r[3])) + ((r[4] + r[5]) + (r[6] + r[7]))
否则,它将对数组的两部分进行递归求和。
因此,在第一种情况下,您得到,a.sum() = a[0] + a[1] + a[2] + a[3]而在第二种情况下b.sum() = (a[0] + a[1]) + (a[2] + a[3]),导致a.sum() - b.sum() != 0




 类似资料:
  • 问题内容: 我有一些带有一些整数的PHP代码,并且一切正常,除非我拥有或作为整数。当我引用它们时,一切都很好。 示例编号: 谁能告诉我背后的原因? 问题答案: 如果您只写08和09(不带引号)或任何其他带有前导0的数字,则PHP认为您正在写一个八进制值,而08和09是无效的八进制数。 http://www.php.net/manual/zh/language.types.integer.php 句

  • 我创建了一个简单的应用程序来模拟JAVAFX的动态节点创建。这个应用程序能够通过单击“新建”按钮在用户需要的时候创建一个新窗口。用户可以通过单击“添加任务”按钮,然后单击对话框窗口上的“添加”按钮,将标题窗格的新节点添加到窗口中。 我想修复一个意外行为。此应用程序仅将新节点(在本例中为TitledPane)添加到最后创建的窗口。并且上一个窗口上的所有节点都将消失。 你可以看下面的视频来更好地理解我

  • 我正在使用Mapstruct映射将一个POJO转换为另一个POJO模型 以下是mapstruct自动生成的方法 该方法基本上获取源POJO的映射,并将其转换为目标模型的映射。生成正在通过。 当我运行代码时,我在这个方法中得到了ClassCast异常:HeaderAttributeGenericDataTypeMaptoStringEnergiectAttributeDataMap 堆栈跟踪: 我还

  • 问题内容: 我似乎在数组上使用时发现了一个陷阱,但是我找不到解释。本质上,如果我尝试对一个大数组求和,那么我会开始得到荒谬的答案,但这是 无声的, 而且我无法充分理解输出结果,而不是Google的原因。 例如,这完全按预期工作: 为两者提供相同的输出: 但是,这不起作用: 提供以下输出: 在更大的阵列上,有可能获得正面的结果。这是更隐蔽的,因为我可能根本不知道发生了什么不寻常的事情。例如: 给出以

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 我有以下代码: 假设我现在将电脑的时区设置为太平洋时间(PDT为UTC-7),则打印 2012年6月29日星期五08:15:00太平洋标准时间 PDT不是比IST(印度标准时间)晚12.5小时吗?这个问题在任何其他时区都不会发生-我尝试了UTC、PKT、MMT等,而不是日期字符串中的IST。Java中有两个IST吗? 注意:实际代码中的日期字符串来自外部源,因此我不能使用GMT偏移量或任何其他时区