向量化的numpy替代插入的实现

时间:2021-04-03 19:33:11

I want to insert zeros in a numpy array but in a different way that the numpy.insert function works. The numpy.insert function inserts every element before the position of the given index without caring about the other elements included in the same insertion. That is, the indexs given to the function refer to positions before the insertion. I would like a function that considers the indices after the insertion. Let me give an example:

我想在numpy数组中插入0,但方式不同于numpy。插入功能是否有效。numpy。插入函数在给定索引的位置之前插入每个元素,而不关心包含在同一插入中的其他元素。也就是说,给函数的索引在插入之前引用位置。我想要一个在插入之后考虑指标的函数。让我举个例子:

If the input array is array(1, 2, 3, 4) and the indices are [2, 5], the output array should be array(1, 2, 0, 3, 4, 0).

如果输入数组是数组(1,2,3,4),而索引是[2,5],则输出数组应该是数组(1,2,0,3,4,0)。

A non-vectorized way to do it would be:

一种非向量化的方法是:

for index in indices:
    input_array = np.insert(input_array, index, 0)

I am looking for a vectorized way to do this, but I cannot find it.

我正在寻找一种矢量化的方法,但是我找不到。

2 个解决方案

#1


1  

Here is a vectorized approach that creates an array of zeros and replaces the items accordingly:

这是一个矢量化的方法,它创建一个零数组,并相应地替换这些项:

In [99]: def insert(arr, ind):
    ...:     new_size = arr.size + ind.size
    ...:     new = np.zeros(new_size)
    ...:     new[~np.in1d(np.arange(new_size), ind)] = arr
    ...:     return new

Demo:

演示:

In [100]: arr = np.array([1, 2, 3, 4])

In [101]: ind = np.array([2, 5])

In [102]: 

In [102]: insert(arr, ind)
Out[102]: array([1., 2., 0., 3., 4., 0.])

#2


1  

Here's one vectorized way with masking -

这是用掩蔽-的矢量化方法

def insert_zeros(input_array, indices):
    n = len(input_array) + len(indices)
    mask = np.ones(n, dtype=bool)
    mask[indices] = 0
    out = mask.astype(input_array.dtype)
    out[mask] = input_array
    return out

Sample run -

样本运行-

In [141]: input_array = np.array([1, 2, 3, 4])
     ...: indices  = np.array([2, 5])

In [142]: insert_zeros(input_array, indices)
Out[142]: array([1, 2, 0, 3, 4, 0])

Benchmarking

Scaling up the given sample by 10,000x on a random numbers array and indices for the timing setup and timing the two posted solutions thus far -

在一个随机数数组和索引上将给定的样本放大10000倍,以用于计时设置和计时两个已发布的解决方案

In [150]: np.random.seed(0)
     ...: input_array = np.random.randint(0,9,(40000))
     ...: indices = np.sort(np.random.choice(range(len(input_array)), 20000, replace=0))

In [151]: %timeit insert(input_array, indices) # @Kasramvd's soln
     ...: %timeit insert_zeros(input_array, indices) # Posted in this soln
100 loops, best of 3: 4.58 ms per loop
1000 loops, best of 3: 280 µs per loop

#1


1  

Here is a vectorized approach that creates an array of zeros and replaces the items accordingly:

这是一个矢量化的方法,它创建一个零数组,并相应地替换这些项:

In [99]: def insert(arr, ind):
    ...:     new_size = arr.size + ind.size
    ...:     new = np.zeros(new_size)
    ...:     new[~np.in1d(np.arange(new_size), ind)] = arr
    ...:     return new

Demo:

演示:

In [100]: arr = np.array([1, 2, 3, 4])

In [101]: ind = np.array([2, 5])

In [102]: 

In [102]: insert(arr, ind)
Out[102]: array([1., 2., 0., 3., 4., 0.])

#2


1  

Here's one vectorized way with masking -

这是用掩蔽-的矢量化方法

def insert_zeros(input_array, indices):
    n = len(input_array) + len(indices)
    mask = np.ones(n, dtype=bool)
    mask[indices] = 0
    out = mask.astype(input_array.dtype)
    out[mask] = input_array
    return out

Sample run -

样本运行-

In [141]: input_array = np.array([1, 2, 3, 4])
     ...: indices  = np.array([2, 5])

In [142]: insert_zeros(input_array, indices)
Out[142]: array([1, 2, 0, 3, 4, 0])

Benchmarking

Scaling up the given sample by 10,000x on a random numbers array and indices for the timing setup and timing the two posted solutions thus far -

在一个随机数数组和索引上将给定的样本放大10000倍,以用于计时设置和计时两个已发布的解决方案

In [150]: np.random.seed(0)
     ...: input_array = np.random.randint(0,9,(40000))
     ...: indices = np.sort(np.random.choice(range(len(input_array)), 20000, replace=0))

In [151]: %timeit insert(input_array, indices) # @Kasramvd's soln
     ...: %timeit insert_zeros(input_array, indices) # Posted in this soln
100 loops, best of 3: 4.58 ms per loop
1000 loops, best of 3: 280 µs per loop