ufuncs are simple and easy to understand once you are able to relate the output they produce on particular array in [ ]arr np arange( reshape( , arr out[ ]array([ ] ][ ]]in [ ]arr out[ ]array([ ][ ][ ]]in [ ]arr out[ ]array([ ][ ][ ]]we see that the standard operators when used in conjunction with arrays work element-wise some ufuncs will take two arrays as input and output single arraywhile rare few will output two arrays also in [ ]arr np arange( reshape( , arr np arange( reshape( , arr arr out[ ]array([ ] ] ][ ][ ]]in [ ]arr out[ ]array([ ] ] ] ][ ]]in [ ]arr out[ ]