我创建了一个像这样的白色棋盘:
import numpy as np
import cv2
checkers = np.tile( np.array([[0, 1], [1, 0]]), (16 // 2, 16 // 2))
但现在我正在努力把它变成一个蓝黄相间的棋盘。
我尝试了一个像这样的lambda转换:
f = lambda x: [0, 255, 0] if x else [255, 255, 255]
checkers = checkers.reshape((256))
checkers = f(checkers)
但我得到一个错误,它说:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
这让我觉得我还没有完全理解lambdas是如何应用于numpy数组的。
我也试过
np.where(checkers == 0, [0, 255, 0], [0, 0, 255])
但我得到了
ValueError: operands could not be broadcast together with shapes (16,16) (3,) (3,)
那么,我如何得到一个双色棋盘,而不是一个黑色和白色?
1条答案
按热度按时间lmyy7pcs1#
你的答案的最后一部分非常接近正确,但它给了你一个错误:操作数不能一起广播。操作数只是指函数参数
checkers == 0
,绿色和蓝色。所以这是一个广播问题。你应该通读一下broadcasting rules,它们会真正改变你对Numpy的理解,让它变得更有用。你的问题是你有一个
checkers
数组,它是2D的,16x16,你希望它“神奇地”转换为3D数组,它是16x16x3。Numpy不做这种神奇的转换。如果数组的最后一个维度是1,Numpy会帮助你重复(广播)数组,让你可以将它与其他数组相乘(或者你想做的任何事情),所以你不必手动在所有三个颜色通道上平铺它。否则,它只会抛出一个错误。解决方案是在
checkers
数组中添加1维。最简单的方法是这会在数组的末尾添加另一个维度,因此可以用你的颜色进行广播。
编辑:关于为什么你的
lambda
方法不起作用,我不确定你是否期望lambda
是一些特殊的东西,但它确实与常规函数没有什么不同。所以你所做的就是也就是说,将整个
checkers
数组一次性传递给函数。然后,Python尝试检查checkers
是否为真,而bool(checkers)
是不明确的,因此它告诉您使用np.all
或np.any
将整个数组减少为一个值。但那不是你想做的。有一些函数,如
np.apply_along_axis
和np.vectorize
,允许您将函数应用于所有值,但您很少需要这样做。你的第二种方法要好得多,你只需要更好地理解广播。