简体   繁体   English

NumPy中的Fancier Fancy Indexing?

[英]Fancier Fancy Indexing in NumPy?

I am implementing color interpolation using a look-up-table (LUT) with NumPy. 我正在使用带有NumPy的查找表(LUT)实现颜色插值。 At one point I am using the 4 most significant bits of RGB values to choose corresponding CMYK values from a 17x17x17x4 LUT. 有一次,我使用RGB值的4个最高位来从17x17x17x4 LUT中选择相应的CMYK值。 Right now it looks something like this: 现在它看起来像这样:

import numpy as np
rgb = np.random.randint(16, size=(3, 1000, 1000))
lut = np.random.randint(256, size=(17, 17, 17, 4))
cmyk = lut[rgb[0], rgb[1], rgb[2]]

Here comes the first question... Is there no better way? 这是第一个问题......没有更好的方法吗? It sort of seems natural that you could tell NumPy that the indices for lut are stored along axis 0 of rgb , without having to actually write it out. 你可以告诉NumPy lut的索引沿着rgb轴0存储,而不必实际写出来,这似乎很自然。 So is there anything like cmyk = lut.fancier_take(rgb, axis=0) in NumPy? 那么在NumPy中有没有类似cmyk = lut.fancier_take(rgb, axis=0)的东西?

Furthermore, I am left with an array of shape (1000, 1000, 4) , so to be consistent with the input, I need to rotate it all around using a couple of swapaxes : 此外,我留下了一个形状阵列(1000, 1000, 4) swapaxes (1000, 1000, 4) ,所以为了与输入一致,我需要使用几个swapaxes来旋转它:

cmyk = cmyk.swapaxes(2, 1).swapaxes(1, 0).copy()

And I also need to add the copy statement, because if not the resulting array is not contiguous in memory, and that brings trouble later on. 而且我还需要添加copy语句,因为如果不是,结果数组在内存中不连续,并且以后会带来麻烦。

Right now I am leaning towards rotating the LUT before the fancy indexing and then do something along the lines of: 现在我倾向于在花式索引之前旋转LUT,然后按照以下方式做一些事情:

swapped_lut = lut.swapaxes(2, 1).swapaxes(1, 0)
cmyk = swapped_lut[np.arange(4), rgb[0], rgb[1], rgb[2]]

But again, it just does not seem right... There has to be a more elegant way to do this, right? 但同样,它似乎并不正确......必须有一种更优雅的方式来做到这一点,对吧? Something like cmyk = lut.even_fancier_take(rgb, in_axis=0, out_axis=0) ... cmyk = lut.even_fancier_take(rgb, in_axis=0, out_axis=0) ......

I'd suggest using tuple to force indexing rowwise, and np.rollaxis or transpose instead of swapaxes : 我建议使用tuple强制逐行索引,而np.rollaxistranspose代替swapaxes

lut[tuple(rgb)].transpose(2, 0, 1).copy()

or 要么

np.rollaxis(lut[tuple(rgb)], 2).copy()

To roll the axis first, use: 要先滚动轴,请使用:

np.rollaxis(lut, -1)[(Ellipsis,) + tuple(rgb)]

You'll need to do the following if you swap lut , np.arange(4) will not work: 如果你交换lut ,你将需要执行以下操作, np.arange(4)将不起作用:

swapped_lut = np.rollaxis(lut, -1)
cmyk = swapped_lut[:, rgb[0], rgb[1], rgb[2]].copy()

Or you can replace 或者你可以替换

cmyk = lut[rgb[0], rgb[1], rgb[2]]
cmyk = cmyk.swapaxes(2, 1).swapaxes(1, 0).copy()

with: 有:

cmyk = lut[tuple(rgb)]
cmyk = np.rollaxis(cmyk, -1).copy()

But to try and do it all in one step, ... Maybe: 但要尝试一步到位,......也许:

rng = np.arange(4).reshape(4, 1, 1)
cmyk = lut[rgb[0], rgb[1], rgb[2], rng]

That's not very readable at all is it? 这根本不是很可读吗?

Take a look at the answer to this question, Numpy multi-dimensional array indexing swaps axis order . 看看这个问题的答案, Numpy多维数组索引交换轴顺序 It does a good job of explaining how numpy broadcasts multiple arrays to get the output size. 它很好地解释了numpy如何广播多个数组以获得输出大小。 Here you want to create indices into lut that broadcast to (4, 1000, 1000). 在这里你想要创建到广播到(4,1000,1000)的lut的索引。 Hope that makes some sense. 希望这有点道理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM