为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Python中的递归加法会产生负数?

为什么Python中的递归加法会产生负数?

SMILET 2023-07-11 16:28:43
我一直在研究Python中的一个函数,该函数查找数组中从各自的索引到数组开头的所有元素的总和。示例: 输入:[2,14,17,36]输出:[2, 14+2, 17+14+2, 36+17+14+2]这是代码。import matplotlib.pyplot as pltimport numpy as nparr = []a = np.array([2, 0, 0, 4, 0, 1, 0, 4, 5, 5])def rolling_sum(x):    total = 0    values = []    for i,j in enumerate(x):        total = total+j         values.append(total)    if total <= 2000000000:        arr.append(values)        return rolling_sum(values)    else:        return valuesrolling_sum(a)for i in arr:    plt.plot(i)检查arr变量发现其中有负数,甚至从图表中也清楚地显示出来。请问为什么会这样呢?
查看完整描述

2 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

当您执行代码时,请注意警告:


RuntimeWarning: overflow encountered in long_scalars

    total = total+j

这是因为numpy有时默认为np.int32(取决于操作系统是 32/64 位并且安装的 Python 解释器是 32/64 位,显然是其中较低的一个)。在这种情况下,大量数字会溢出,因此它们会换行为负数。


通过提供以下内容可以轻松解决此问题dtype=np.int64:


a = np.array([2, 0, 0, 4, 0, 1, 0, 4, 5, 5], dtype=np.int64)

这可以通过添加以下内容来确认:


from itertools import chain


print(len(list(filter(lambda n: n < 0, chain.from_iterable(arr)))))

这会展平arr并计算有多少个负数。使用原始代码,输出是


RuntimeWarning: overflow encountered in long_scalars

  total = total+j

5

添加后dtype=np.int64输出是


0


查看完整回答
反对 回复 2023-07-11
?
胡子哥哥

TA贡献1825条经验 获得超6个赞

NumPy 数组使用固定大小的整数类型(例如) ,这与大小不受限制的int64常规 Python 类型不同。int

它们具有可以代表的最大值。尝试添加大于此最大值的值会导致溢出,这可能会导致有符号整数类型出现负值。

例如,该类型的最大值int32为 2 31 −1 = 2147483647,加 1 得到最小值 −2 31 = −2147483648。对于int64类型来说,这些值要大得多;分别为9223372036854775807和-9223372036854775808。根据您的实现(即 NumPy 默认使用的类型)和您使用的输入,您可能会或可能不会看到此行为。

就您而言,与 Python 列表相比,您似乎没有使用 NumPy 数组提供的任何功能,因此您可以只使用a = [2, 0, 0, 4, 0, 1, 0, 4, 5, 5]并依赖 Python 为您处理无限的大整数。


查看完整回答
反对 回复 2023-07-11
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信