I have a working solution to my problem, but when trying different things I was astounded there wasn't a better solution that I could find. It all boils down to creating a single flexible dtype value for comparing and inserting into an array.
I have an RGB 24-bit image (so 8-bits for each R, G, and B) image array. It turns out for some actions it is best to use it as a 3D array with HxWx3 other times it is best to use it as a structured array with the dtype([('R',uint8),('G',uint8),('B',uint8)]). One example is when trying to relabel the image colors so that every unique color is given a different value. I do this with the following code:
# Given im as an array of HxWx3, dtype=uint8 from numpy import dtype, uint8, unique, insert, searchsorted rgb_dtype = dtype([('R',uint8),('G',uint8),('B',uint8)])) im = im.view(dtype=rgb_dtype).squeeze() # need squeeze to remove the third dim values = unique(im) if tuple(values[0]) != (0, 0, 0): values = insert(values, 0, 0) # value 0 needs to always be (0, 0, 0) labels = searchsorted(values, im) This works beautifully, however I am tried to make the if statement look nicer and just couldn't find a way. So lets look at the comparison first:
>>> values[0] (0, 0, 0) >>> values[0] == 0 False >>> values[0] == (0, 0, 0) False >>> values[0] == array([0, 0, 0]) False >>> values[0] == array([uint8(0), uint8(0), uint8(0)]).view(dtype=rgb_dtype)[0] True >>> values[0] == zeros((), dtype=rgb_dtype) True But what if you wanted something besides (0, 0, 0) or (1, 1, 1) and something that was not ridiculous looking? It seems like there should be an easier way to construct this, like rgb_dtype.create((0,0,0)).
Next with the insert statement, you need to insert 0 for (0, 0, 0). For other values this really does not work, for example inserting (1, 2, 3) actually inserts (1, 1, 1), (2, 2, 2), (3, 3, 3).
So in the end, is there a nicer way? Thanks!