array multiplication with different dtypes
I'm having a difficult time understanding the following behavior: import numpy as N # create a new array 4 rows, 3 columns x = N.random.random((4, 3)) # elementwise multiplication x*x newtype = N.dtype([('x', N.float64), ('y', N.float64), ('z', N.float64)]) # interpret the array as an array of cartesian coordinates x.dtype = newtype x*x --> TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and ' numpy.ndarray' N.__version__ '1.0.2.dev3498' So just by assigning names to the columns, I can't multiply the arrays any more? Numpy itself still claims that x is an ndarray. I hope this is a bug, because it would be really convenient if this still worked after assigning names to columns. What I really wanted to do was N.dot(x, x.T) to get the length of the cartesian vectors, but (I think) this fails for the same reason. Please tell me this is a bug ;-) Cheers, Jan
Jan Strube wrote:
I'm having a difficult time understanding the following behavior:
import numpy as N # create a new array 4 rows, 3 columns x = N.random.random((4, 3)) # elementwise multiplication x*x
newtype = N.dtype([('x', N.float64), ('y', N.float64), ('z', N.float64)])
# interpret the array as an array of cartesian coordinates x.dtype = newtype
x*x
--> TypeError: unsupported operand type(s) for *: ' numpy.ndarray' and 'numpy.ndarray'
N.__version__ '1.0.2.dev3498'
So just by assigning names to the columns, I can't multiply the arrays any more?
No, it's not a bug. It's a "missing feature"." You have created a "record-array". All of the ufuncs are undefined for arrays with fields (what is sometimes called a variable item-size array). They are undefined for two reasons 1) It's not clear how to define them. It is ambiguous in general. For this specific case, it is probably clear what you want, but what do you want for the general case data-type with fields defined. This has never been thought out clearly. 2) It's not trivial to implement. Basically, handling the general case would require some alterations to the main ufunc code loops in order to pass information about the size of the array element that is presently not available. Perhaps some day we will be able to add element-by-element ufuncs for record arrays that will basically recurse through the fields, but that will require some coding effort that is not on my radar for the next while. What you can do, is maintain a view of the data as a 4x3 array of floats and do the multiplication with that array. The same memory can then also be viewed as a length 4 1-d array of coordinates if you like. You can also be more explicit about what you want to do with each column by writing y = x.copy() y['x'] = x['x']*x['x'] y['y'] = x['y']*x['y'] y['z'] = x['z']*x['z']
Please tell me this is a bug ;-)
Sorry, it's not that easy. -Travis
participants (2)
-
Jan Strube
-
Travis Oliphant