多维数组的Numpy arctan2



我正在尝试编写一些代码,以获取单个float值,因此使用1D(最终2D) numpy.arrays作为输入可以很好地工作。

条纹到一个最小的例子,函数看起来像这样(不,这个例子没有做任何有用的,但如果do_mathdo_some_more_math被删除,它将产生完全描述的行为):

def do_complicated_math(r, g, b):
    rgb = numpy.array([r, g, b])
    # Math! No change in array shape. To run example just comment out.
    rgb = do_math(rgb)
    m_2 = numpy.array([[rgb[0], 0, 0], [0, rgb[1], 0], [0, 0, rgb[2]]])
    # Get additional matrices needed for transformation.
    # These are actually predefined 3x3 float arrays
    m_1 = numpy.ones((3, 3))
    m_3 = numpy.ones((3, 3))
    # Transform the rgb array
    rgb_transformed = m_1.dot(m_2).dot(m_3).dot(rgb)
    # More math! No change in array shape. To run example just comment out.
    rgb_transformed = do_some_more_math(rgb_transformed)
    # Almost done just one more thing...
    return numpy.arctan2(rgb_transformed, rgb_transformed)
# Works fine
do_complicated_math(1, 1, 1)
# Fails
x = numpy.ones(6)
do_complicated_math(x, x, x)

只要r, gb是单独的数字,这个函数就可以正常工作,但是,如果它们作为numpy.array给出(例如,为了一次转换多个rgb值),numpy.arctan2会抛出以下异常:

Traceback (most recent call last):
  (...) line 32, in do_complicated_math
    numpy.arctan2(rgb_transformed, rgb_transformed)
AttributeError: 'numpy.ndarray' object has no attribute 'arctan2'

我还没有找到任何明确的答案,这是试图告诉我什么。arctan2似乎可以很好地与以下多维数组一起使用:

numpy.arctan2(numpy.ones((3,4,5)), numpy.ones((3,4,5)))

所以我认为问题必须在m_2如何创建的某个地方,或者m_1, m_2, m_3rgb的乘法如何传播,但我似乎无法弄清楚它在哪里破裂。

问题是,rgb_transformed不再是一个标准numpy数组,当你把它传递给arctan2,它已经成为一个对象数组:

print rgb_transformed
"""[[array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])]
 [array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])]
 [array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])
  array([ 9.,  9.,  9.,  9.,  9.,  9.])]]"""
print rgb_transformed.shape
#(3, 6)
print rgb_transformed.dtype
#object

所以这个问题比我想象的要简单:

这条线

:

m_2 = numpy.array([[rgb[0], 0, 0], [0, rgb[1], 0], [0, 0, rgb[2]]])
print m_2
#array([[array([ 1.,  1.,  1.,  1.,  1.,  1.]), 0, 0],
#       [0, array([ 1.,  1.,  1.,  1.,  1.,  1.]), 0],
#       [0, 0, array([ 1.,  1.,  1.,  1.,  1.,  1.])]], dtype=object)

这里创建对象数组,并在其余代码中传播。

编辑

要解决这个问题,您可能需要稍微改变广播数组的方式。基本上改变外部维度来反映变化的rgb值。免责声明:在您的问题上下文中,我没有很好的方法来验证此结果,因此请谨慎对待输出。

import numpy as np
def do_complicated_math(r, g, b):
    rgb = np.array([r, g, b])
    # create a transposed version of the m_2 array
    m_2 = np.zeros((r.size,3,3))
    for ii,ar in enumerate(rgb):
        m_2[:,ii][:,ii][:] = ar
    m_1 = np.ones((3, 3))
    m_3 = np.ones((3, 3))
    rgb_transformed = m_1.dot(m_2).dot(m_3).dot(rgb)
    print rgb_transformed
    return np.arctan2(rgb_transformed, rgb_transformed)
x = np.ones(6)
do_complicated_math(x, x, x)                                                                                                                        
r = np.array([0.2,0.3,0.1])
g = np.array([1.0,1.0,0.2])
b = np.array([0.3,0.3,0.3])
do_complicated_math(r, g, b)

这将只对数组作为输入工作,但是添加对单个值作为输入的处理应该是微不足道的。

相关内容

  • 没有找到相关文章

最新更新