为何np.sin(x)与np.cos(x)绝对值在0到2π的采样和不相等?
np.sin(x)与np.cos(x)绝对值采样和不相等的原因
问题描述
我尝试计算np.sin(x)与np.cos(x)的绝对值之和,因为二者在0到2π区间的积分结果都是4,所以觉得它们的采样和也应该相等,但实际运行结果却有差异。
我写的Python代码如下:
import numpy as np angles = np.linspace(0, 2*np.pi, 1000) line1, line2= [], [] for n in angles: line1.append(np.abs(np.cos(n))) line2.append(np.abs(np.sin(n))) print(sum(line1), sum(line2))
运行后输出:
636.983414656738 635.9826284722284
二者的和差了近1,想知道是哪里考虑漏了,还是这是个bug?
原因解析
这不是bug,问题出在np.linspace的端点设置上:
- 默认情况下
np.linspace(0, 2*np.pi, 1000)会生成包含首尾两个端点的1000个均匀采样点,也就是第一个点是0,最后一个点是2π。 - 对于
np.abs(np.cos(x)),x=0和x=2π时的值都是1;而np.abs(np.sin(x))在这两个点的值都是0。 - 这就导致余弦的采样和多了两个1的贡献,而正弦在这两个点没有任何贡献,最终拉开了两者的差距。
- 原本在0到2π区间内,cos和sin的绝对值是对称的,但首尾端点的特殊值打破了这种采样上的对称。
解决方法
如果让采样区间不包含2π这个端点,也就是给linspace加上endpoint=False参数,生成的1000个点是从0到接近2π的位置,此时两者的采样和会几乎完全相等:
import numpy as np angles = np.linspace(0, 2*np.pi, 1000, endpoint=False) sum_cos = np.sum(np.abs(np.cos(angles))) sum_sin = np.sum(np.abs(np.sin(angles))) print(sum_cos, sum_sin)
运行结果示例:
636.4829774655923 636.4829774655923
另外建议用numpy的向量化操作替代循环,代码更简洁,运行效率也更高。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

