Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在numpy中交换多个值的子集_Numpy_Swap_Array Broadcasting - Fatal编程技术网

在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,

给定一个如下所示的起始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, 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
的大小,并准确定义你所说的效率是什么?在记忆或时间方面是否有效?