Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/numpy/doc/ufuncs.py
7762 views
"""1===================2Universal Functions3===================45Ufuncs are, generally speaking, mathematical functions or operations that are6applied element-by-element to the contents of an array. That is, the result7in each output array element only depends on the value in the corresponding8input array (or arrays) and on no other array elements. NumPy comes with a9large suite of ufuncs, and scipy extends that suite substantially. The simplest10example is the addition operator: ::1112>>> np.array([0,2,3,4]) + np.array([1,1,-1,2])13array([1, 3, 2, 6])1415The ufunc module lists all the available ufuncs in numpy. Documentation on16the specific ufuncs may be found in those modules. This documentation is17intended to address the more general aspects of ufuncs common to most of18them. All of the ufuncs that make use of Python operators (e.g., +, -, etc.)19have equivalent functions defined (e.g. add() for +)2021Type coercion22=============2324What happens when a binary operator (e.g., +,-,\\*,/, etc) deals with arrays of25two different types? What is the type of the result? Typically, the result is26the higher of the two types. For example: ::2728float32 + float64 -> float6429int8 + int32 -> int3230int16 + float32 -> float3231float32 + complex64 -> complex643233There are some less obvious cases generally involving mixes of types34(e.g. uints, ints and floats) where equal bit sizes for each are not35capable of saving all the information in a different type of equivalent36bit size. Some examples are int32 vs float32 or uint32 vs int32.37Generally, the result is the higher type of larger size than both38(if available). So: ::3940int32 + float32 -> float6441uint32 + int32 -> int644243Finally, the type coercion behavior when expressions involve Python44scalars is different than that seen for arrays. Since Python has a45limited number of types, combining a Python int with a dtype=np.int846array does not coerce to the higher type but instead, the type of the47array prevails. So the rules for Python scalars combined with arrays is48that the result will be that of the array equivalent the Python scalar49if the Python scalar is of a higher 'kind' than the array (e.g., float50vs. int), otherwise the resultant type will be that of the array.51For example: ::5253Python int + int8 -> int854Python float + int8 -> float645556ufunc methods57=============5859Binary ufuncs support 4 methods.6061**.reduce(arr)** applies the binary operator to elements of the array in62sequence. For example: ::6364>>> np.add.reduce(np.arange(10)) # adds all elements of array65456667For multidimensional arrays, the first dimension is reduced by default: ::6869>>> np.add.reduce(np.arange(10).reshape(2,5))70array([ 5, 7, 9, 11, 13])7172The axis keyword can be used to specify different axes to reduce: ::7374>>> np.add.reduce(np.arange(10).reshape(2,5),axis=1)75array([10, 35])7677**.accumulate(arr)** applies the binary operator and generates an an78equivalently shaped array that includes the accumulated amount for each79element of the array. A couple examples: ::8081>>> np.add.accumulate(np.arange(10))82array([ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45])83>>> np.multiply.accumulate(np.arange(1,9))84array([ 1, 2, 6, 24, 120, 720, 5040, 40320])8586The behavior for multidimensional arrays is the same as for .reduce(),87as is the use of the axis keyword).8889**.reduceat(arr,indices)** allows one to apply reduce to selected parts90of an array. It is a difficult method to understand. See the documentation91at:9293**.outer(arr1,arr2)** generates an outer operation on the two arrays arr1 and94arr2. It will work on multidimensional arrays (the shape of the result is95the concatenation of the two input shapes.: ::9697>>> np.multiply.outer(np.arange(3),np.arange(4))98array([[0, 0, 0, 0],99[0, 1, 2, 3],100[0, 2, 4, 6]])101102Output arguments103================104105All ufuncs accept an optional output array. The array must be of the expected106output shape. Beware that if the type of the output array is of a different107(and lower) type than the output result, the results may be silently truncated108or otherwise corrupted in the downcast to the lower type. This usage is useful109when one wants to avoid creating large temporary arrays and instead allows one110to reuse the same array memory repeatedly (at the expense of not being able to111use more convenient operator notation in expressions). Note that when the112output argument is used, the ufunc still returns a reference to the result.113114>>> x = np.arange(2)115>>> np.add(np.arange(2),np.arange(2.),x)116array([0, 2])117>>> x118array([0, 2])119120and & or as ufuncs121==================122123Invariably people try to use the python 'and' and 'or' as logical operators124(and quite understandably). But these operators do not behave as normal125operators since Python treats these quite differently. They cannot be126overloaded with array equivalents. Thus using 'and' or 'or' with an array127results in an error. There are two alternatives:1281291) use the ufunc functions logical_and() and logical_or().1302) use the bitwise operators & and \\|. The drawback of these is that if131the arguments to these operators are not boolean arrays, the result is132likely incorrect. On the other hand, most usages of logical_and and133logical_or are with boolean arrays. As long as one is careful, this is134a convenient way to apply these operators.135136"""137138139