2.2.2.1 他们是什么?

  • Ufunc在数组的所有元素上进行元素级操作。

例子:

np.addnp.subtractscipy.special.*, …

  • 自动话支持:广播、投射…
  • ufunc的作者只提供了元素级操作,Numpy负责剩下的。
  • 元素级操作需要在C中实现(或者比如Cython)

2.2.2.1.1 Ufunc的部分

  • 由用户提供

In [ ]:

  1. void ufunc_loop(void **args, int *dimensions, int *steps, void *data)
  2. {
  3. /*
  4. * int8 output = elementwise_function(int8 input_1, int8 input_2)
  5. *
  6. * This function must compute the ufunc for many values at once,
  7. * in the way shown below.
  8. */
  9. char *input_1 = (char*)args[0];
  10. char *input_2 = (char*)args[1];
  11. char *output = (char*)args[2];
  12. int i;
  13. for (i = 0; i < dimensions[0]; ++i) {
  14. *output = elementwise_function(*input_1, *input_2);
  15. input_1 += steps[0];
  16. input_2 += steps[1];
  17. output += steps[2];
  18. }
  19. }
  • Numpy部分,由下面的代码创建

In [ ]:

  1. char types[3]
  2. types[0] = NPY_BYTE /* type of first input arg */
  3. types[1] = NPY_BYTE /* type of second input arg */
  4. types[2] = NPY_BYTE /* type of third input arg */
  5. PyObject *python_ufunc = PyUFunc_FromFuncAndData(
  6. ufunc_loop,
  7. NULL,
  8. types,
  9. 1, /* ntypes */
  10. 2, /* num_inputs */
  11. 1, /* num_outputs */
  12. identity_element,
  13. name,
  14. docstring,
  15. unused)
  1. - ufunc也可以支持多种不同输入输出类型组合。

2.2.2.1.2 简化一下

ufunc_loop是非常通用的模式,Numpy提供了预制

PyUfunc_f_ffloat elementwise_func(float input_1)
PyUfunc_ff_ffloat elementwise_func(float input_1, float input_2)
PyUfunc_d_ddouble elementwise_func(double input_1)
PyUfunc_dd_ddouble elementwise_func(double input_1, double input_2)
PyUfunc_D_Delementwise_func(npy_cdouble *input, npy_cdouble* output)
PyUfunc_DD_Delementwise_func(npy_cdouble *in1, npy_cdouble *in2, npy_cdouble* out)
  1. - 只有需要提供`elementwise_func`
  2. - ... 除非当你的元素级函数不是上面的形式中的任何一种