【问题标题】:Understanding == applied to a NumPy array理解 == 应用于 NumPy 数组
【发布时间】:2016-07-31 06:39:46
【问题描述】:

我是 Python 新手,正在学习 TensorFlow。在使用 notMNIST 数据集的教程中,他们提供了将标签矩阵转换为 n 之一编码数组的示例代码。

目标是获取一个由标签整数 0...9 组成的数组,并返回一个矩阵,其中每个整数都已转换为一个 n 之一编码数组,如下所示:

0 -> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
2 -> [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
...

他们给出的代码是:

# Map 0 to [1.0, 0.0, 0.0 ...], 1 to [0.0, 1.0, 0.0 ...]
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)

但是,我根本不明白这段代码是如何做到的。看起来它只是生成一个 0 到 9 范围内的整数数组,然后将其与标签矩阵进行比较,并将结果转换为浮点数。 == 运算符如何生成 one-of-n 编码矩阵

【问题讨论】:

    标签: python python-2.7 numpy


    【解决方案1】:

    这里发生了一些事情:numpy 的向量操作、添加单例轴和广播。

    首先,您应该能够看到== 是如何发挥作用的。

    假设我们从一个简单的标签数组开始。 == 以向量化方式运行,这意味着我们可以将整个数组与一个标量进行比较,并获得一个由每个元素比较的值组成的数组。例如:

    >>> labels = np.array([1,2,0,0,2])
    >>> labels == 0
    array([False, False,  True,  True, False], dtype=bool)
    >>> (labels == 0).astype(np.float32)
    array([ 0.,  0.,  1.,  1.,  0.], dtype=float32)
    

    首先我们得到一个布尔数组,然后我们强制转换为浮点数:在 Python 中为 False==0,而 True==1。所以我们最终得到一个数组,它是 0,labels 不等于 0,而 1 是它所在的位置。

    但是与 0 比较并没有什么特别之处,我们可以与 1 或 2 或 3 进行比较以获得相似的结果:

    >>> (labels == 2).astype(np.float32)
    array([ 0.,  1.,  0.,  0.,  1.], dtype=float32)
    

    事实上,我们可以遍历所有可能的标签并生成这个数组。我们可以使用 listcomp:

    >>> np.array([(labels == i).astype(np.float32) for i in np.arange(3)])
    array([[ 0.,  0.,  1.,  1.,  0.],
           [ 1.,  0.,  0.,  0.,  0.],
           [ 0.,  1.,  0.,  0.,  1.]], dtype=float32)
    

    但这并没有真正利用 numpy.我们要做的是将每个可能的标签与每个元素进行比较,IOW 进行比较

    >>> np.arange(3)
    array([0, 1, 2])
    

    >>> labels
    array([1, 2, 0, 0, 2])
    

    这就是 numpy 广播的魔力所在。现在,labels 是形状 (5,) 的一维对象。如果我们将其设为形状为 (5,1) 的二维对象,则操作将在最后一个轴上“广播”,我们将获得形状为 (5,3) 的输出以及比较每个条目的结果标签的每个元素的范围。

    首先我们可以使用None(或np.newaxis)为labels添加一个“额外”轴,改变它的形状:

    >>> labels[:,None]
    array([[1],
           [2],
           [0],
           [0],
           [2]])
    >>> labels[:,None].shape
    (5, 1)
    

    然后我们可以进行比较(这是我们之前看到的安排的转置,但这并不重要)。

    >>> np.arange(3) == labels[:,None]
    array([[False,  True, False],
           [False, False,  True],
           [ True, False, False],
           [ True, False, False],
           [False, False,  True]], dtype=bool)
    >>> (np.arange(3) == labels[:,None]).astype(np.float32)
    array([[ 0.,  1.,  0.],
           [ 0.,  0.,  1.],
           [ 1.,  0.,  0.],
           [ 1.,  0.,  0.],
           [ 0.,  0.,  1.]], dtype=float32)
    

    numpy 中的广播功能非常强大,值得一读。

    【讨论】:

    • 一个非常详细和好的解释。大多数参加 Udacity 深度学习课程的人一定偶然发现了这个答案。
    【解决方案2】:

    简而言之,== 应用于 numpy 数组意味着将元素方式 == 应用于数组。结果是一个布尔数组。这是一个例子:

    >>> b = np.array([1,0,0,1,1,0])
    >>> b == 1
    array([ True, False, False,  True,  True, False], dtype=bool)
    

    要计算b 中有多少个 1,您不需要将数组转换为浮点数,即可以保存 .astype(np.float32),因为在 python 中 boolean 是 int 的子类,而在 Python 3你有True == 1 False == 0。所以这里是你如何计算b中有多少个:

    >>> np.sum((b == 1))
    3
    

    或者:

    >>> np.count_nonzero(b == 1)
    3
    

    【讨论】:

      猜你喜欢
      • 2018-09-07
      • 2015-08-13
      • 2020-04-03
      • 1970-01-01
      • 2019-07-25
      • 2019-11-27
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多