在numpy中交换多个值的子集
给定一个如下所示的起始numpy数组:在numpy中交换多个值的子集,numpy,swap,array-broadcasting,Numpy,Swap,Array Broadcasting,给定一个如下所示的起始numpy数组: B = np.array( [1, 1, 1, 0, 2, 2, 1, 3, 3, 0, 4, 4, 4, 4] ) 当存在重复值时,将一组值交换为另一组值的最有效方法是什么?例如,让 s1 = [1,2,4] s2 = [4,1,2] 低效的交换方法会遍历s1和s2,因此: B2 = B.copy() for x,y in zip(s1,s2): B2[B==x] = y 作为输出给予 B2 -> [4, 4, 4, 0, 1, 1,
B = np.array( [1, 1, 1, 0, 2, 2, 1, 3, 3, 0, 4, 4, 4, 4] )
当存在重复值时,将一组值交换为另一组值的最有效方法是什么?例如,让
s1 = [1,2,4]
s2 = [4,1,2]
低效的交换方法会遍历s1
和s2
,因此:
B2 = B.copy()
for x,y in zip(s1,s2):
B2[B==x] = y
作为输出给予
B2 -> [4, 4, 4, 0, 1, 1, 4, 3, 3, 0, 2, 2, 2, 2]
有没有一种方法可以在不使用
zip
循环的情况下实现这一点?如果只有介于0和n之间的整数(如果推广到任何整数范围都没有问题,除非它非常稀疏),最有效的方法是使用take/fancy索引:
>>> B = np.array( [1, 1, 1, 0, 2, 2, 1, 3, 3, 0, 4, 4, 4, 4] )
>>> s1 = [1,2,4]
>>> s2 = [4,1,2]
>>> B2 = B.copy()
>>> c, d = np.where(B == np.array(s1)[:,np.newaxis])
>>> B2[d] = np.repeat(s2,np.bincount(c))
>>> B2
array([4, 4, 4, 0, 1, 1, 4, 3, 3, 0, 2, 2, 2, 2])
swap = np.arange(B.max() + 1) # all values in B
swap[s1] = s2 # replace the values you want to be replaced
B2 = swap.take(B) # or swap[B]
这似乎是这里给出的小B速度的两倍,但对于较大的B,重复B到大约100000的长度时,速度会更快,已经达到8倍。这也避免了对每个s1元素执行==操作,因此当s1/s2变大时,可以更好地扩展
编辑:您还可以使用np.put(也在另一个答案中)来加速
交换[s1]=s2
。对于这些1D问题,take/put的速度更快。答案不错(+1),但它将相当消耗内存。不过,我不确定我是否有更好的解决方案。你应该给出B
和s1
和s2
的大小,并准确定义你所说的效率是什么?在记忆或时间方面是否有效?