Numpy arrays let you apply numeric operators to all elements in the array. So array * 3
would apply the multiplication to all elements in the array, producing a new array with the results. You can use an array on either side of such an expression; after all, not all operators are commutative.
Using 2 ** array
simply applies each element in the array as an exponent of 2, producing an array with the 2 ** <input item>
calculation:
>>> arange(8, 12, .25)
array([ 8. , 8.25, 8.5 , 8.75, 9. , 9.25, 9.5 , 9.75,
10. , 10.25, 10.5 , 10.75, 11. , 11.25, 11.5 , 11.75])
>>> 2**arange(8, 12, .25)
array([ 256. , 304.43702144, 362.03867197, 430.53896461,
512. , 608.87404288, 724.07734394, 861.07792922,
1024. , 1217.74808576, 1448.15468787, 1722.15585844,
2048. , 2435.49617153, 2896.30937574, 3444.31171688])
So the input is an array with 8
, 8.25
, 8.5
, etc., and the resulting array contains the result of 2 ** 8
, 2 ** 8.25
, 2 ** 8.5
, and so on.
The array.astype(int)
operation then floors the results:
>>> (2 ** arange(8, 12, .25)).astype(int)
array([ 256, 304, 362, 430, 512, 608, 724, 861, 1024, 1217, 1448,
1722, 2048, 2435, 2896, 3444])