32

I'd like to multiply an int16 array but a float array, with auto rounding, but this fails :

import numpy

A = numpy.array([1, 2, 3, 4], dtype=numpy.int16)
B = numpy.array([0.5, 2.1, 3, 4], dtype=numpy.float64)

A *= B

I get:

TypeError: Cannot cast ufunc multiply output from dtype('float64') to dtype('int16') with casting rule 'same_kind'

seralouk
  • 30,938
  • 9
  • 118
  • 133
Basj
  • 41,386
  • 99
  • 383
  • 673
  • It seems it's possible with `numpy.multiply(A, B, out=A, casting='unsafe')` but that's way much longer syntax! Is there a way to set casting='unsafe' in numpy by default? – Basj Jul 30 '16 at 12:10
  • 1
    See https://github.com/numpy/numpy/pull/6499/files – Basj Jul 30 '16 at 12:11

3 Answers3

41

2 ways to solve this:

You can solve this by replacing

A *= B

with

A = (A * B)

or with

numpy.multiply(A, B, out=A, casting='unsafe')
seralouk
  • 30,938
  • 9
  • 118
  • 133
4

You could use broadcasting to multiply the two arrays and take only the integer part as follows:

In [2]: (A*B).astype(int)
Out[2]: array([ 0,  4,  9, 16])

Timing Constraints:

In [8]: %timeit (A*B).astype(int)
1000000 loops, best of 3: 1.65 µs per loop

In [9]: %timeit np.multiply(A, B, out=A, casting='unsafe')
100000 loops, best of 3: 2.01 µs per loop
Nickil Maveli
  • 29,155
  • 8
  • 82
  • 85
  • OP wants to do the multiplication in place – ali_m Jul 30 '16 at 18:45
  • How fast is it compared to `numpy.multiply(A, B, out=A, casting='unsafe')` ? – Basj Jul 30 '16 at 18:45
  • 1
    @ali_m Nowhere does the OP mention they want to do the multiplication in place. Their only comment was that the longer way was "way much longer syntax". – SethMMorton Jul 30 '16 at 18:51
  • @SethMMorton Well, both the example given in the question and the workaround the OP posted in the comments are explicitly performing in place multiplication. – ali_m Jul 30 '16 at 18:56
  • 3
    @ali_m I don't disagree with that, but based on this question and [the other question](http://stackoverflow.com/q/38673878/1399279) it seems the OP is more interested in terseness than an in-place operation. Having said that, I think the assumption that they want an in place operation is good because of the examples given and that in-place saves having to type `A = `, but I always think it is safer to wait for the OP to explicitly make it clear what they want rather than make assumptions. – SethMMorton Jul 30 '16 at 18:59
  • @SethMMorton Perfectly explicit questions are very rare on SO - if you wait for total clarity you are likely to wait forever. The best we can do is to ask for clarification in the comments and try to infer what the OP wants based on the evidence available. Given that my answer was accepted I'm reasonably confident that I guessed right, but the OP can always unaccept my answer if they change their mind ;-) – ali_m Jul 30 '16 at 19:12
3
import numpy as np

A = np.float_(A)
A *= B

try this. I think are different array type you get fail.

Cast