I'm trying to use the np.ceil function on a structrued numpy array, but all I get is the error message:

TypeError: ufunc 'ceil' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Here's a simply example of what that array would look like:

arr = np.array([(1.4,2.3), (3.2,4.1)], dtype=[("x", "<f8"), ("y", "<f8")])

When I try

np.ceil(arr)

I get the above mentioned error. When I just use one column, it works:

In [77]: np.ceil(arr["x"])
Out[77]: array([ 2.,  4.])

But I need to get the entire array. Is there any way other than going column by column, or not using structured arrays all together?

1 Answers

0
kevinkayaks On

Here's a dirty solution based on viewing the array without its structure, taking the ceiling, and then converting it back to a structured array.

# sample array
arr = np.array([(1.4,2.3), (3.2,4.1)], dtype = [("x", "<f8"), ("y", "<f8")])
# remove struct and take the ceiling
arr1 = np.ceil(arr.view((float, len(arr.dtype.names))))
# coerce it back into the struct
arr = np.array(list(tuple(t) for t in arr1), dtype = arr.dtype)
# kill the intermediate copy
del arr1 

and here it is as an unreadable one-liner but without assigning the intermediate copy arr1

arr = np.array(
    list(tuple(t) for t in np.ceil(arr.view((float, len(arr.dtype.names))))),
    dtype = arr.dtype
              )

# array([(2., 3.), (4., 5.)], dtype=[('x', '<f8'), ('y', '<f8')])

I don't claim this is a great solution, but it should help you move on with your project until something better is proposed