[Numpy-discussion] Priority rules between numpy scalars and 0d arrays

Pierre GM pgmdevlist@gmail....
Mon Oct 13 13:30:29 CDT 2008


Travis, 

> The problem is that there has never been a formal "resolution" (that I
> recall) of when should something be returned as a 0-d array and when it
> should be returned as a scalar.   There is rather an informal
> implementation of what actually happens.

Ah. It might be worth putting the current informal rules or rule-of-thumb 
black-on-white (or green-on-black) somewhere

> The other issue is that there is the rule that when scalars and arrays
> mix, the "data-type" of the array determines the result, but there
> aren't fixed rules about what the "sub-type" should be.

I would expect something like "return a scalar unless specified otherwise by a 
subclass".

> Could you post code to describe what you mean?

In MaskedArray, we check whether the output of an operation is 0d: if it is 
and that the result is masked, then ma.masked is output. if the result is 0d 
without a mask, a numpy scalar is output.

ma.masked is defined as MaskedArray(0,mask=True,dtype=np.float)

First, let's check the left multiplication

>>> ma.masked * 1
masked_array(data = --,
      mask = True,
      fill_value=1e+20)
>>> ma.masked * np.float64(1)
masked_array(data = --,
      mask = True,
      fill_value=1e+20)
>>> ma.masked * np.float128(1)
masked_array(data = --,
      mask = True,
      fill_value=1e+20)

Everythng works as planned.

Now, for the right multiplication:
>>> 1.*ma.masked
masked_array(data = --,
      mask = True,
      fill_value=1e+20)
>>> np.float64(1)*ma.masked
0.0
>>> np.float128(1)*ma.masked
0.0

And that's where the problem is. It looks like ma.masked.__rmul__ or 
ma.masked.__mul__ are *NOT* called in the last two cases, when I expected it 
would.

But if we have a 1d array:
>>> np.array(1., dtype=np.float128)*ma.masked
masked_array(data = --,
      mask = True,
      fill_value=1e+20)

> I think the issue is that numpy scalars are currently wrapped into 0-d
> arrays for all math and so the 'priority' issue might really an issue
> between numpy arrays and masked arrays.

I don't think it's a problem of __array__priority__. MaskedArrays have 
currently a __array_priority__ of 15, switching to 1e99 or even np.inf 
doesn't change anything. It looks like the dtype is checked first, which 
dictates which method is being called (ndarray.__mul__ instead of 
MaskedArray.__rmul__).
What surprises me also is that numpy scalar are supposed to have a very low 
priority (negative).

In short, Travis, could you explain me what's happening ?




More information about the Numpy-discussion mailing list