【问题标题】:How to create a Boolean array from an array of indices in numpy?如何从 numpy 中的索引数组创建布尔数组?
【发布时间】:2018-06-06 01:53:29
【问题描述】:

鉴于我有一个多维索引数组,我如何从这些索引创建一个布尔数组?对于一维情况,它看起来像这样:

a = [1,5,6]
b = somefunction(total_array_length=10, a)
>>> [False, True, False, False, False, True, True, False, False, False]

对于 2D 情况,它看起来像这样:

a = [[1,3],[4,2]]
b = somefunction(total_array_length=5, a)
>>> [[False, True, False, True, False], [False, False, True, False, True]]

我想用它来为数组创建掩码。我有一个维度为 8 的多维数组,对于最后一个轴,我可以找到我想要保留的元素的索引。换句话说,我有一个 8D 数组,其中最后一个轴包含我想保留在原始数组中的所有索引。有人知道怎么做吗?

在上面的函数中,total_array_length 将等于原始数组的长度。

那么我将如何为形状为 (23,5,76,32,1,3,8,9) 的数组执行此操作,索引数组的形状为 (23,5,76,32,1,3,8 ,4)?注意 4

a.shape = (23,5,76,32,1,3,8,4) 
b = somefunction(total_array_length=9, a)
b.shape =(23,5,76,32,1,3,8,9) 

【问题讨论】:

  • 不清楚total_array_length 是什么以及为什么b 的形状与a 的形状在这两个示例中都不匹配。此外,还不清楚您要对 8d 数组的最后一个轴说什么。这听起来与您的示例不相似。
  • 如果遇到困难,请尝试编写代码并发布。不要要求我们从头开始。
  • 我说清楚了吗?

标签: python arrays numpy multidimensional-array mask


【解决方案1】:

对于一维:

n = 10
inds_all = np.arange(n)
inds = [1, 5, 6]

b = np.isin(inds_all, inds)
# array([False, True, False, False, False, True, True, False, False, False])

对于 2D 来说,这有点棘手,尤其是当列表索引列表的大小不均匀时:

n = 5
inds_all = np.arange(len(inds)*n).reshape(len(inds), n)
inds = [[1,3], [4,2], [3]]
inds = np.concatenate(inds) + np.repeat(inds_all[:,0], list(map(len, inds)))

b = np.isin(inds_all, inds)
# array([[False,  True, False,  True, False],
#        [False, False,  True, False,  True],
#        [False, False, False,  True, False]])

【讨论】:

    【解决方案2】:

    对于第一种情况:

    In [23]: a = [1,5,6]
    In [24]: b = np.zeros(10, dtype=bool)
    In [25]: b[a] = True
    In [26]: b
    Out[26]: array([False,  True, False, False, False,  True,  True, False, False, False], dtype=bool)
    

    同样简单且可能同样快速的列表版本:

    In [27]: [True if i in a else False for i in range(10)]
    Out[27]: [False, True, False, False, False, True, True, False, False, False]
    

    对于列表列表,只需嵌套列表理解:

    In [34]: [[True if i in a1 else False for i in range(5)] for a1 in a]
    Out[34]: [[False, True, False, True, False], [False, False, True, False, True]]
    

    第二种情况的数组版本是:

    In [41]: a = [[1,3],[4,2]]
    In [42]: b = np.zeros((len(a),5), bool)
    In [43]: b[[[0],[1]],a]
    Out[43]: 
    array([[False, False],
           [False, False]], dtype=bool)
    In [44]: b[[[0],[1]],a]=True
    In [45]: b
    Out[45]: 
    array([[False,  True, False,  True, False],
           [False, False,  True, False,  True]], dtype=bool)
    

    不过,这只有在a 的子列表长度相同时才有效。如果它们不同,我认为我们将不得不使用它的扁平化版本。实际上是把 2d 的 case 变成了原来的 1d。


    对于一个衣衫褴褛的a,列表版还是很简单的:

    In [49]: a = [[1,2,3],[4,2],[1]]
    In [50]: [[True if i in a1 else False for i in range(5)] for a1 in a]
    Out[50]: 
    [[False, True, True, True, False],
     [False, False, True, False, True],
     [False, True, False, False, False]]
    

    但数组版本涉及更多:

    为行和列构造 2 个索引数组:

    In [53]: a0 = np.repeat(np.arange(3),[len(i) for i in a])
    In [54]: a0
    Out[54]: array([0, 0, 0, 1, 1, 2])
    In [55]: a1 = np.hstack(a)
    In [56]: a1
    Out[56]: array([1, 2, 3, 4, 2, 1])
    

    获取等效的 raveled (1d) 索引:

    In [57]: np.ravel_multi_index((a0,a1),(3,5))
    Out[57]: array([ 1,  2,  3,  9,  7, 11], dtype=int32)
    

    通过flat 将其应用于二维数组:

    In [58]: b = np.zeros((3,5),bool)
    In [59]: b.flat[Out[57]] = True
    In [60]: b
    Out[60]: 
    array([[False,  True,  True,  True, False],
           [False, False,  True, False,  True],
           [False,  True, False, False, False]], dtype=bool)
    

    【讨论】:

    • 如何为形状为 (23,5,76,32,1,3,8,9) 的数组执行此操作,索引数组为 (23,5,76,32,1 ,3,8,4)?注意 4
    • 尝试将数组重塑为 (n,4) 和 (n,9)。进行映射(例如 44)。然后重新塑形。
    • True if i in a1 else Falsei in a1 相同,使用后者会更快、更易读。
    猜你喜欢
    • 2013-06-19
    • 2021-01-06
    • 1970-01-01
    • 2021-11-29
    • 2017-09-24
    • 1970-01-01
    • 2020-03-25
    • 2012-01-03
    • 2015-05-19
    相关资源
    最近更新 更多