如何在给定索引范围列表的情况下有效地将1-D numpy数组的0设置为1

koaltpgm  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(109)

我有一个索引范围列表,我想在1-D numpy数组中设置为相同的值。
例如,考虑以下索引范围列表:

[(0,1), (3,8), (9,11)]

字符串
我希望我的zero-ed数组看起来像这样,如果我将值设置为1:

[1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1., 0., 0., 0., 0.]


我想尽可能高效地完成它,最好没有for循环。现有的帖子,如this one,使用广播为2-D阵列做了这件事,但不清楚如何将其适应1-D。
例如,这起作用:

indices_range_list = [(0,1), (3,8), (9,11)]
my_array = np.zeros(15)
for r in indices_range_list:
   my_array[r[0]:r[1]] = 1
print(my_array)


输出量:

array([1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1., 0., 0., 0., 0.])

dluptydi

dluptydi1#

使用np.r_(将切片对象转换为串联)+ np.put例程:

ind_ranges = [(0,1), (3,8), (9,11)]
arr = np.zeros(15)
np.put(arr, np.r_[*[slice(*r) for r in ind_ranges]], 1)

字符串
最终arr

array([1., 0., 0., 1., 1., 1., 1., 1., 0., 1., 1., 0., 0., 0., 0.])

tuwxkamq

tuwxkamq2#

您可以通过创建给定范围内所有索引的列表来索引所有必要的索引,然后使用该列表进行索引。

my_array = np.zeros(15)
indices = np.hstack([np.arange(*vals) for vals in indices_range_list])
my_array[indices] = 1
print(my_array)

字符串
输出量:

[1. 0. 0. 1. 1. 1. 1. 1. 0. 1. 1. 0. 0. 0. 0.]


尽管这不会在主数组上循环,但它比原始代码慢,因为构建indices数组需要时间。

zpjtge22

zpjtge223#

我运行了timeit,似乎没有一个建议的解决方案比for循环更快:

python3 -m timeit -s 'import numpy as np; ind_ranges = [(0,1), (3,8), (9,11)]; arr = np.zeros(15)' 'np.put(arr, np.r_[*[slice(*r) for r in ind_ranges]], 1)'

字符串
50000个循环,五局两胜:5.93 usec/循环

python3 -m timeit -s 'import numpy as np; ind_ranges = [(0,1), (3,8), (9,11)]; arr = np.zeros(15)' 'for s,e in ind_ranges: arr[s:e] = 1'


500000个循环,五局两胜:542纳秒/循环
所以看起来for循环是最有效的,至少在这些简单的测试中是这样。

相关问题