numpy中的multiply()函数

2 投票
2 回答
688 浏览
提问于 2025-04-17 07:19

我觉得numpy的multiply()函数有两个版本:

  1. c = multiply( a, b ) 这个版本是把结果存到变量c里。
  2. multiply(a, b, c) 这个版本是直接把结果放到已经存在的变量c里。

我有两个问题:

  1. 这两个版本有什么区别呢?
  2. 我需要用到dot()函数,我知道c = dot( a, b)可以用,但dot(a, b, c)却不行。

2 个回答

1

所有标准的numpy ufuncs(即通用函数)只有一个版本——我们以“dot”函数为例。

Type:           builtin_function_or_method
Base Class:     <type 'builtin_function_or_method'>
String Form:    <built-in function dot>
Namespace:      Interactive
Docstring:
    dot(a, b, out=None)

Dot product of two arrays.

For 2-D arrays it is equivalent to matrix multiplication, and for 1-D
arrays to inner product of vectors (without complex conjugation). For
N dimensions it is a sum product over the last axis of `a` and
the second-to-last of `b`::

    dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

Parameters
----------
a : array_like
    First argument.
b : array_like
    Second argument.
out : ndarray, optional
    Output argument. This must have the exact kind that would be returned
    if it was not used. In particular, it must have the right type, must be
    C-contiguous, and its dtype must be the dtype that would be returned
    for `dot(a,b)`. This is a performance feature. Therefore, if these
    conditions are not met, an exception is raised, instead of attempting
    to be flexible.

如果你提供了一个可选的第三个参数,并且这个参数的类型和存储顺序是正确的,那么它就会正常工作:

In [78]: a=np.array([1.,2.,3.,4.])

In [79]: b=np.diag(a)

In [80]: c=np.empty_like(a)

In [81]: np.dot(a,b,c)
Out[81]: array([  1.,   4.,   9.,  16.])

In [82]: np.dot(a,b)
Out[82]: array([  1.,   4.,   9.,  16.])
6
  1. 关于两个版本的 multiply() 的区别:

    c = multilpy(a, b)
    

    这个版本是对数组 ab 进行逐元素相乘,结果会生成一个新的数组。这里的 c 就是指向这个新数组。如果 c 之前指向的是另一个数组,那么是否会清理掉之前的数组就要看还有没有其他地方在用这个数组了。

    multilpy(a, b, c)
    

    这个版本同样是对数组 ab 逐元素相乘,但结果会存储在已有的数组 c 中(这个数组必须有合适的大小)。这里不会创建新的数组对象,而是直接修改已有的数组。除了语义上的不同,如果 c 已经指向一个合适类型和大小的数组,这个版本会更快,因为不需要分配新的数组。这个版本还可以减少内存的使用。

  2. 这其实不是一个问题。是的,dot() 并没有三参数的形式。它不是一个通用函数(ufunc),也不遵循通常的广播规则——因为点积的语义决定了它不能这样做。

    编辑:从 NumPy 1.6 开始,dot() 确实有了一个三参数的形式,语义和上面解释的类似。(顺便提一下,它仍然不是一个通用函数。)

撰写回答