切片numpy的数组另一个数组 [英] Slicing numpy array with another array

查看:234
本文介绍了切片numpy的数组另一个数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我需要切片整数关有很大一维数组。这是微不足道的,我只是做 A [开始:结束] 。问题是,我需要更多的这些片。 A [开始:结束] 如果起点和终点是数组不起作用。 For循环可用于这一点,但我需要它尽可能快(这是一个瓶颈),所以本地numpy的解决方案将受到欢迎。

要进一步说明,我有这样的:

  A = numpy.array([0,1,2,3,4,5,6,7,8,9,10,11],numpy.int16)
开始= numpy.array([1,5,7],numpy.int16)
端= numpy.array([2,10,10],numpy.int16)

和需要以某种方式使之变成这样:

  [1],[5,6,7,8,9],[7,8]


解决方案

这可能(几乎?)可以在纯使用屏蔽阵列和步幅技巧 numpy的完成。首先,我们创建面膜:

 >>>指数= numpy.arange(a.size)
>>>面膜=〜((指数> =启动[:,无])及(指数<结束[:,无]))

或者更简单地说:

 >>>屏蔽=(指数<启动[:,无])| (指数> =结束[:,无])

掩码是(没有被屏蔽即值)对于那些指标是> = 来启动价值和< 最终值。 (与切片无(又名 numpy.newaxis )增加了一个新的层面,使广播)。现在我们的面具看起来像这样的:

 >>>面具
阵列([真,假,真,真,真,真,真,真,真,
         不错,不错,真]
       [不错,不错,不错,不错,真,假,假,假,假,
        假,真,真]
       [不错,不错,不错,不错,不错,不错,真,假,假,
         不错,不错,真],DTYPE =布尔)

现在我们来舒展阵列使用,以适应面具 stride_tricks

 >>> as_strided = numpy.lib.stride_tricks.as_strided
>>>跨入= as_strided(一,mask.shape,(0,a.strides [0]))
>>>跨进
阵列([0,1,2,3,4,5,6,7,8,9,10,11],
       [0,1,2,3,4,5,6,7,8,9,10,11],
       [0,1,2,3,4,5,6,7,8,9,10,11],DTYPE = INT16)

这看起来像一个3x12阵列,但在相同的存储器的每一行分。现在,我们可以将它们组合成一个蒙面的数组:

 >>> numpy.ma.array(跨进,面膜面膜=)
masked_array(数据=
 [[ - 1 - - - - - - - - - - ]
 [ - - - - - 5 6 7 8 9 - - ]
 [ - - - - - - - 7 8 - - - ],
             面膜=
 [真假真真真真真真真真真真]
 [真真真真真假假假假假真真]
 [真真真真真真真假假真真真],
       fill_value = 999999)

这是不太一样的,你问什么,但它应该的行为类似。

I've got a large one-dimensional array of integers I need to take slices off. That's trivial, I'd just do a[start:end]. The problem is that I need more of these slices. a[start:end] does not work if start and end are arrays. For loop could be used for this, but I need it to be as fast as possible (it is a bottleneck), so a native numpy solution would be welcome.

To further illustrate, I have this:

a = numpy.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], numpy.int16)
start = numpy.array([1, 5, 7], numpy.int16)
end   = numpy.array([2, 10, 9], numpy.int16)

And need to somehow make it into this:

[[1], [5, 6, 7, 8, 9], [7, 8]] 

解决方案

This can (almost?) be done in pure numpy using masked arrays and stride tricks. First, we create our mask:

>>> indices = numpy.arange(a.size)
>>> mask = ~((indices >= start[:,None]) & (indices < end[:,None]))

Or more simply:

>>> mask = (indices < start[:,None]) | (indices >= end[:,None])

The mask is False (i.e. values not masked) for those indices that are >= to the start value and < the end value. (Slicing with None (aka numpy.newaxis) adds a new dimension, enabling broadcasting.) Now our mask looks like this:

>>> mask
array([[ True, False,  True,  True,  True,  True,  True,  True,  True,
         True,  True,  True],
       [ True,  True,  True,  True,  True, False, False, False, False,
        False,  True,  True],
       [ True,  True,  True,  True,  True,  True,  True, False, False,
         True,  True,  True]], dtype=bool)

Now we have to stretch the array to fit the mask using stride_tricks:

>>> as_strided = numpy.lib.stride_tricks.as_strided
>>> strided = as_strided(a, mask.shape, (0, a.strides[0]))
>>> strided
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]], dtype=int16)

This looks like a 3x12 array, but each row points at the same memory. Now we can combine them into a masked array:

>>> numpy.ma.array(strided, mask=mask)
masked_array(data =
 [[-- 1 -- -- -- -- -- -- -- -- -- --]
 [-- -- -- -- -- 5 6 7 8 9 -- --]
 [-- -- -- -- -- -- -- 7 8 -- -- --]],
             mask =
 [[ True False  True  True  True  True  True  True  True  True  True  True]
 [ True  True  True  True  True False False False False False  True  True]
 [ True  True  True  True  True  True  True False False  True  True  True]],
       fill_value = 999999)

This isn't quite the same as what you asked for, but it should behave similarly.

这篇关于切片numpy的数组另一个数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆