Numpy数组打印特定值的索引

5

给定一个numpy数组

A = np.array([[[29, 64, 83],
               [17, 92, 38],
               [67, 34, 20]],
              [[73, 28, 45],
               [19, 84, 61],
               [22, 63, 49]],
              [[48, 30, 13],
               [11, 52, 86],
               [62, 25, 12]]])

我想要某个值的索引,比如说63

这个值不会重复也不会缺失

我已经做了

idx = np.where(A == 63)

print(idx)

I got

(array([1], dtype=int32), array([2], dtype=int32), array([1], dtype=int32))

What I want is

[1, 2, 1]

如何在不涉及array, dtype=int32等内容的情况下,将其作为列表或其他可迭代对象处理?

我该怎么做呢?

3个回答

3
这种方法使用列表推导怎么样?
   idx = [x[0] for x in np.where(A==63)]

看起来可以工作。谢谢。我需要研究一下才能理解它在做什么。 - Barry Andersen
如果你想了解列表推导式的工作原理,请查看它。 - memecs
我不明白的是 x[0] 中的 0 是做什么的。 - Barry Andersen
它正在从数组[...]中提取值。 - memecs

3

如果你想要得到一个numpy数组,只需要使用concatenate函数:

In [30]: np.concatenate(idx)
Out[30]: array([1, 2, 1])

如果您真的想要使用Python列表,那么只需执行以下操作:

In [31]: np.concatenate(idx).tolist()
Out[31]: [1, 2, 1]

1
Numpy数组支持在条件为真时返回元素。您可以使用np.where(..)或使用以下方法:
>>> A==63
array([[[False, False, False],
        [False, False, False],
        [False, False, False]],

       [[False, False, False],
        [False, False, False],
        [False,  True, False]],

       [[False, False, False],
        [False, False, False],
        [False, False, False]]], dtype=bool)

然后,您可以使用数组的.nonzero()方法将该索引数组压平为仅包含“True”值:

>>> (A==63).nonzero()
(array([1]), array([2]), array([1]))

注意,这是由numpy数组组成的Python元组,第一个数组是X索引,第二个是Y索引,第三个是Z索引,在A[X,Y,Z]的形式下。
对于只有一个元素的情况,您可以使用.r_来展开它:
>>> np.r_[(A==63).nonzero()]
array([1, 2, 1])

如果你愿意,你可以生成一个Python列表:

>>> np.r_[(A==63).nonzero()].tolist()
[1, 2, 1]

更有趣的用例是当矩阵中有多个索引为True时。考虑所有大于63的值:

>>> A>63
array([[[False,  True,  True],
        [False,  True, False],
        [ True, False, False]],

       [[ True, False, False],
        [False,  True, False],
        [False, False, False]],

       [[False, False, False],
        [False, False,  True],
        [False, False, False]]], dtype=bool)

你也可以使用 .nonzero() 方法或者 nonzero 函数:

>>> np.nonzero(A>63)
(array([0, 0, 0, 0, 1, 1, 2]), array([0, 0, 1, 2, 0, 1, 1]), array([1, 2, 1, 0, 0, 1, 2]))
     ^^^ X's                      ^^^ Y's                              ^^^ Z's

注意,现在这是一个由三个数组组成的元组(在这种情况下),按照顺序是所有X、所有Y、所有Z。
您可以使用np.transpose生成这种形式的元素索引数组[[X,Y,Z],...],如下所示:
>>> np.transpose((A>63).nonzero())
array([[0, 0, 1],
       [0, 0, 2],
       [0, 1, 1],
       [0, 2, 0],
       [1, 0, 0],
       [1, 1, 1],
       [2, 1, 2]])

或者(例如适合人类眼睛打印)您可以使用zip:
>>> zip(*(A>63).nonzero())
[(0, 0, 1), (0, 0, 2), (0, 1, 1), (0, 2, 0), (1, 0, 0), (1, 1, 1), (2, 1, 2)]

或者,打印:

>>> print '\n'.join([str(e) for e in zip(*(A>63).nonzero())])
(0, 0, 1)
(0, 0, 2)
(0, 1, 1)
(0, 2, 0)
(1, 0, 0)
(1, 1, 1)
(2, 1, 2)

当然,这同样适用于单个元素:

>>> zip(*(A==63).nonzero())[0]
(1, 2, 1)

或者 numpy 的方式:
>>> np.transpose((A==63).nonzero())[0]
array([1, 2, 1])

所有这里的方法都可以使用np.where(A==63)代替(A==63).nonzero()作为示例。请注意,这里不保留中文标点符号,以及格式要求,请您提前告知需要翻译的内容中是否包含代码块等特殊要求。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接