问题描述
问题
请建议我如何理解为什么空列表/数组的乘积为 1 以及 numpy.prod 的行为的方法。任何好的阅读,到目前为止我找不到任何文章(如底部)。
空数组的乘积是中性元素 1
np.prod([])
1.0 ```
为什么空数组a = np.empty((1,5),dtype=float)
的乘积是0
而不是1
?如果定义 product of empty list/array is 1
为真,那么我想它应该是 1。
a = np.empty((1,dtype=float)
a.prod()
---
0
背景
混淆为什么乘积(数组中元素的乘法)是1
,而不是0
。研究了文章,但找不到明确的解释。
math.prod([2,3,5]) # = 30
math.prod([2,3]) # = 6
math.prod([2]) # = 2
math.prod([]) # = 1
(* 2 2 2) ; evaluates to 8
(* 2 2) ; evaluates to 4
(* 2) ; evaluates to 2
(*) ; evaluates to 1
它似乎与范畴论有关,但解释很神秘,无法理解它试图解释的内容。
您可以在此处找到分类产品的完整定义。以下 我给出的定义忽略了当我们查看时会消失的细节 空产品。
一组对象的乘积是一个对象 P 使得给定任何 另一个对象 X … 存在一个从 X 到 P 的唯一态射,使得 ....
如果您以前从未见过这种情况,您可能理所当然地想知道 这与产品有关的世界。你必须相信我 这个。
当对象集为空时,定义的缺失部分 以上无关紧要,所以我们只剩下要求有一个 从每个对象 X 到乘积 P 的唯一态射。 话,P是终端对象,常记为1。所以在范畴论中, 您可以说空产品为 1。
解决方法
np.prod
的代码是:
return _wrapreduction(a,np.multiply,'prod',axis,dtype,out,keepdims=keepdims,initial=initial,where=where)
换句话说就是:
In [176]: np.multiply.reduce(np.arange(1,6))
Out[176]: 120
如果我们改用 accumulate
,这个动作可能会更清楚:
In [177]: np.multiply.accumulate(np.arange(1,6))
Out[177]: array([ 1,2,6,24,120])
基本上 np.prod
是 np.sum
的乘法等价物。
如果您查看 np.multiply.reduce
的文档,您将获得对一般 ufunc.reduce
方法的描述。它涉及一个 initial
值,该值可能是默认值,也可能是用户特定的。所有 reduce
操作都必须从某些东西开始,最好是在上下文中有意义的东西。当参数为空时,该初始值将适用 - 0 个值。
In [181]: np.multiply.reduce(np.arange(1,6),initial=10)
Out[181]: 1200
In [182]: np.multiply.reduce(np.arange(1,initial=0)
Out[182]: 0
请注意,我必须从 1 开始 arange
。如果参数中有任何 0,则 prod
将为 0!。
In [184]: np.multiply.reduce([],initial=0)
Out[184]: 0.0
In [185]: np.multiply.reduce([],initial=1)
Out[185]: 1.0
In [186]: np.multiply.reduce([],initial=10)
Out[186]: 10.0
至于你对 np.empty
函数的困惑,你有没有仔细看 a
?
In [187]: np.empty((1,5),float)
Out[187]: array([[4.9e-324,9.9e-324,1.5e-323,2.0e-323,2.5e-323]])
In [188]: np.array([])
Out[188]: array([],dtype=float64)
np.empty
产生的结果与 np.array([])
不同。请注意形状((1,5) 与 (0,) 以及值的差异)。