Numpy将输入数组作为ufunc的`out`参数传递 [英] Numpy passing input array as `out` argument to ufunc

查看:136
本文介绍了Numpy将输入数组作为ufunc的`out`参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只要类型正确,将输入数组作为ufunc中的ufunc的可选out参数提供,通常是安全的吗?例如,我已经验证了以下功能:

Is it generally safe to provide the input array as the optional out argument to a ufunc in numpy, provided the type is correct? For example, I have verified that the following works:

>>> import numpy as np
>>> arr = np.array([1.2, 3.4, 4.5])
>>> np.floor(arr, arr)
array([ 1.,  3.,  4.])

数组类型必须与输出兼容或相同(对于numpy.floor()是浮点型),否则会发生这种情况:

The array type must be either compatible or identical with the output (which is a float for numpy.floor()), or this happens:

>>> arr2 = np.array([1, 3, 4], dtype = np.uint8)
>>> np.floor(arr2, arr2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'floor' output (typecode 'e') could not be coerced to provided output parameter (typecode 'B') according to the casting rule ''same_kind''

因此,考虑到适当类型的数组,通常就地应用ufuncs是否安全?还是floor()是例外情况?该文档没有明确说明,与问题有切线关系的以下两个线程也没有:

So given that an array of proper type, is it generally safe to apply ufuncs in-place? Or is floor() an exceptional case? The documentation does not make it clear, and neither do the following two threads that have tangential bearing on the question:

  1. 是否在适当的地方修改了数组?
  2. Numpy Ceil和地板"out";争论
  1. Numpy modify array in place?
  2. Numpy Ceil and Floor "out" Argument

根据

As a first order guess, I would assume it is often, but not always safe, based on the tutorial at http://docs.scipy.org/doc/numpy/user/c-info.ufunc-tutorial.html. There does not appear to be any restriction on using the output array as a temporary holder for intermediate results during the computation. While something like floor() and ciel() may not require temporary storage, more complex functions might. That being said, the entire existing library may be written with that in mind.

推荐答案

numpy函数的out参数是写入结果的数组.使用out的主要优点是避免在不必要的情况下分配新内存.

The out parameter of a numpy function is the array where the result is written. The main advantage of using out is avoiding the allocation of new memory where it is not necessary.

将函数的输出写在作为输入传递的同一数组上是否安全?没有通用的答案,这取决于函数的功能.

Is it safe to use write the output of a function on the same array passed as input? There is no general answer, it depends on what the function is doing.

以下是类似ufunc的函数的两个示例:

Here are two examples of ufunc-like functions:

In [1]: def plus_one(x, out=None):
   ...:     if out is None:
   ...:         out = np.zeros_like(x)
   ...: 
   ...:     for i in range(x.size):
   ...:         out[i] = x[i] + 1
   ...:     return out
   ...: 

In [2]: x = np.arange(5)

In [3]: x
Out[3]: array([0, 1, 2, 3, 4])

In [4]: y = plus_one(x)

In [5]: y
Out[5]: array([1, 2, 3, 4, 5])

In [6]: z = plus_one(x, x)

In [7]: z
Out[7]: array([1, 2, 3, 4, 5])

功能shift_one:

In [11]: def shift_one(x, out=None):
    ...:     if out is None:
    ...:         out = np.zeros_like(x)
    ...: 
    ...:     n = x.size
    ...:     for i in range(n):
    ...:         out[(i+1) % n] = x[i]
    ...:     return out
    ...: 

In [12]: x = np.arange(5)

In [13]: x
Out[13]: array([0, 1, 2, 3, 4])

In [14]: y = shift_one(x)

In [15]: y
Out[15]: array([4, 0, 1, 2, 3])

In [16]: z = shift_one(x, x)

In [17]: z
Out[17]: array([0, 0, 0, 0, 0])

对于功能plus_one,没有问题:当参数x和out是同一数组时,可以获得预期的结果.但是当参数x和out是同一数组时,函数shift_one给出了令人惊讶的结果,因为该数组

For the function plus_one there is no problem: the expected result is obtained when the parameters x and out are the same array. But the function shift_one gives a surprising result when the parameters x and out are the same array because the array

对于形式为out[i] := some_operation(x[i])的函数,例如上面的plus_one,还可以说是函数floor,ceil,sin,cos,tan,log,conj等,据我所知安全使用参数out将结果写到输入中.

For function of the form out[i] := some_operation(x[i]), such as plus_one above but also the functions floor, ceil, sin, cos, tan, log, conj, etc, as far as I know it is safe to write the result in the input using parameter out.

对于采用两个格式为``out [i]:= some_operation(x [i],y [i])的两个输入参数的函数(例如numpy函数add,乘,减去.

It is also safe for functions taking two input parameters of the form ``out[i] := some_operation(x[i], y[i]) such as the numpy function add, multiply, subtract.

对于其他功能,视情况而定.如图所示,矩阵乘法是不安全的:

For the other functions, it is case-by-case. As illustrated bellow, the matrix multiplication is not safe:

In [18]: a = np.arange(4).reshape((2,2))

In [19]: a
Out[19]: 
array([[0, 1],
       [2, 3]])

In [20]: b = (np.arange(4) % 2).reshape((2,2))

In [21]: b
Out[21]: 
array([[0, 1],
       [0, 1]], dtype=int32)

In [22]: c = np.dot(a, b)

In [23]: c
Out[23]: 
array([[0, 1],
       [0, 5]])

In [24]: d = np.dot(a, b, out=a)

In [25]: d
Out[25]: 
array([[0, 1],
       [0, 3]])

最后说明::如果实现是多线程的,则不安全函数的结果甚至可能是不确定的,因为它取决于处理数组元素的顺序.

Last remark: if the implementation is multithreaded, the result of an unsafe function may even be non-deterministic because it depends on the order on which the array elements are processed.

这篇关于Numpy将输入数组作为ufunc的`out`参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆