I have pandas dataframe like this:
x | y | color | |
---|---|---|---|
0 | 826 | 1048 | 52416 |
1 | 583 | 1031 | 9745407 |
2 | 1873 | 558 | 6970623 |
3 | 1627 | 255 | 40618 |
4 | 49 | 1478 | 9745407 |
5 | 408 | 1863 | 14986239 |
6 | 111 | 1582 | 9745407 |
7 | 1334 | 1840 | 6970623 |
8 | 1908 | 1854 | 6970623 |
and numpy array which acts like a image canvas with shape (width, height, 4)
, pandas X and Y are within the width and height range of the canvas array.
What would be an effective way to split the RGBA integer values into it's respective channels and then put these into canvas as denoted by it's X,Y?
Currently I was able to separate the RGBA with numpy like this:
np_data = dataframe.to_numpy(np.uint32)
rgb_channels = np_data[:, 2].view(np.uint8).reshape(np_data[:, 2].shape[0], 4)
but I was unable to apply the values effectively thru numpy:
# This does not work
np.put(canvas, ((np_data[:, 0] * canvas.shape[0]) (np_data[:, 1]), rgb_channels)
# I guess rgb_channels would have to have same size as canvas, as the index is applied to both (?) instead of the value argument being consumed for each index
The only way that works is this in python:
i = 0 # couldn't make enumerate or numpy.ndenumerate work properly
for x, y in np_data[:, [0, 1]]: # loop thru X,Y coordinates
canvas[x][y] = rgb_channels[i]
CodePudding user response:
Your approach would go something like this:
np_data = (df['color'].to_numpy()
.astype('uint32') # uint32
.view('uint8') # convert to uint8
.reshape(len(df), -1) # reshape
)
# new image
canvas = np.zeros((10,10,4), dtype='uint8')
# slicing
canvas[df['x'], df['y']] = np_data
I would parse the channels explicitly like this
# use [3,2,1,0] if you are working with RGBA
powers = 256 ** np.array([2,1,0])
colors = (df.color.to_numpy()[:,None] & (powers*255))// powers
out = np.zeros((10,10,3), dtype='uint8')
out[df['x'], df['y']] = colors