[英]Assign multiple values to multiple slices of a numpy array at once
我有一個numpy數組,一個定義數組范圍的開始/結束索引列表,以及一個值列表,其中值的數量與范圍的數量相同。 在循環中執行此賦值當前非常慢,因此我想以矢量化方式將值分配給數組中的相應范圍。 這可能嗎?
這是一個具體的簡化示例:
a = np.zeros([10])
這里是開始的列表和內定義范圍結束索引列表a
,是這樣的:
starts = [0, 2, 4, 6]
ends = [2, 4, 6, 8]
這是我要為每個范圍分配的值列表:
values = [1, 2, 3, 4]
我有兩個問題。 第一個是我無法弄清楚如何使用多個切片同時索引到數組,因為范圍列表是在實際代碼中動態構造的。 一旦我能夠提取范圍,我不確定如何一次分配多個值 - 每個范圍一個值。
以下是我嘗試創建切片列表以及使用該列表索引數組時遇到的問題:
slices = [slice(start, end) for start, end in zip(starts, ends)]
In [97]: a[slices]
...
IndexError: too many indices for array
In [98]: a[np.r_[slices]]
...
IndexError: arrays used as indices must be of integer (or boolean) type
如果我使用靜態列表,我可以一次提取多個切片,但隨后分配不能按我想要的方式工作:
In [106]: a[np.r_[0:2, 2:4, 4:6, 6:8]] = [1, 2, 3]
/usr/local/bin/ipython:1: DeprecationWarning: assignment will raise an error in the future, most likely because your index result shape does not match the value array shape. You can use `arr.flat[index] = values` to keep the old behaviour.
#!/usr/local/opt/python/bin/python2.7
In [107]: a
Out[107]: array([ 1., 2., 3., 1., 2., 3., 1., 2., 0., 0.])
我真正想要的是這個:
np.array([1。,1.,2.,2.,3.,3.,4.,4.,0.,0。])
這將以完全矢量化的方式完成:
counts = ends - starts
idx = np.ones(counts.sum(), dtype=np.int)
idx[np.cumsum(counts)[:-1]] -= counts[:-1]
idx = np.cumsum(idx) - 1 + np.repeat(starts, counts)
a[idx] = np.repeat(values, count)
一種可能性是使用值壓縮開始,結束索引並手動廣播索引和值:
starts = [0, 2, 4, 6]
ends = [2, 4, 6, 8]
values = [1, 2, 3, 4]
a = np.zeros(10)
import numpy as np
# calculate the index array and value array by zipping the starts, ends and values and expand it
idx, val = zip(*[(list(range(s, e)), [v] * (e-s)) for s, e, v in zip(starts, ends, values)])
# assign values
a[np.array(idx).flatten()] = np.array(val).flatten()
a
# array([ 1., 1., 2., 2., 3., 3., 4., 4., 0., 0.])
或者寫一個for循環來為另一個范圍分配值:
for s, e, v in zip(starts, ends, values):
a[slice(s, e)] = v
a
# array([ 1., 1., 2., 2., 3., 3., 4., 4., 0., 0.])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.