给出两个数组,比如说
arr = array([10, 24, 24, 24, 1, 21, 1, 21, 0, 0], dtype=int32)
rep = array([3, 2, 2, 0, 0, 0, 0, 0, 0, 0], dtype=int32)
np.repeat(arr,rep)返回
array([10, 10, 10, 24, 24, 24, 24], dtype=int32)
有没有办法为一组2D数组复制此功能?
给出了
arr = array([[10, 24, 24, 24, 1, 21, 1, 21, 0, 0],
[10, 24, 24, 1, 21, 1, 21, 32, 0, 0]], dtype=int32)
rep = array([[3, 2, 2, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)
是否可以创建一个矢量化的函数?
PS:每行中的重复次数不必相同。我填充每个结果行以确保它们具有相同的大小。
def repeat2d(arr, rep):
# Find the max length of repetitions in all the rows.
max_len = rep.sum(axis=-1).max()
# Create a common array to hold all results. Since each repeated array will have
# different sizes, some of them are padded with zero.
ret_val = np.empty((arr.shape[0], maxlen))
for i in range(arr.shape[0]):
# Repeated array will not have same num of cols as ret_val.
temp = np.repeat(arr[i], rep[i])
ret_val[i,:temp.size] = temp
return ret_val
我知道np.vectorize,我知道它不会比普通版本带来任何性能优势。
答案 0 :(得分:4)
所以每行有不同的重复数组?但每行的重复总数是一样的吗?
只需在展平的数组上执行repeat
,然后重新塑造回正确的行数。
In [529]: np.repeat(arr,rep.flat)
Out[529]: array([10, 10, 10, 24, 24, 24, 24, 10, 10, 24, 24, 24, 24, 1])
In [530]: np.repeat(arr,rep.flat).reshape(2,-1)
Out[530]:
array([[10, 10, 10, 24, 24, 24, 24],
[10, 10, 24, 24, 24, 24, 1]])
如果每行的重复次数不同,我们就会遇到填充变长行的问题。其他SO问题出现了。我不记得所有细节,但我认为解决方案就在这条线上:
更改rep
以使数字不同:
In [547]: rep
Out[547]:
array([[3, 2, 2, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 1, 0, 2, 0, 0, 0, 0]])
In [548]: lens=rep.sum(axis=1)
In [549]: lens
Out[549]: array([7, 9])
In [550]: m=np.max(lens)
In [551]: m
Out[551]: 9
创建目标:
In [552]: res = np.zeros((arr.shape[0],m),arr.dtype)
创建索引数组 - 需要详细说明:
In [553]: idx=np.r_[0:7,m:m+9]
In [554]: idx
Out[554]: array([ 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17])
平面索引分配:
In [555]: res.flat[idx]=np.repeat(arr,rep.flat)
In [556]: res
Out[556]:
array([[10, 10, 10, 24, 24, 24, 24, 0, 0],
[10, 10, 24, 24, 24, 24, 1, 1, 1]])
答案 1 :(得分:1)
另一种类似于@ hpaulj解决方案的解决方案:
def repeat2dvect(arr, rep):
lens = rep.sum(axis=-1)
maxlen = lens.max()
ret_val = np.zeros((arr.shape[0], maxlen))
mask = (lens[:,None]>np.arange(maxlen))
ret_val[mask] = np.repeat(arr.ravel(), rep.ravel())
return ret_val
我没有存储索引,而是创建一个bool掩码并使用掩码来设置值。