2017-07-08 97 views
1

我正在尝试解决以下问题。我有两个矩阵A和B,并且我想创建一个新的矩阵C,矩阵C由矩阵A和B的行组成,这取决于在数组v中编码的一些条件,即如果v的第i个条目是那么我希望第i行的C是B的第i行,如果它是零,那么它应该是A的第i行。我想出了以下解决方案:从两个矩阵中选择行

C = np.choose(v,A.T,B.T).T 

但它太慢了。一个显而易见的坏处是两个转置,但是由于np.choose没有轴参数,所以我不知道如何摆脱它们。任何想法快速解决这个问题?

例如,让

A = np.arange(20).reshape([4,5]) 

B = 10 - A 

那么可以想像,一个人想矩阵C是行用最小的最大标准的矩阵。所以,我们让

v = np.sum(A,axis=1)<np.sum(B,axis=1) 

,然后C是矩阵

C = np.choose(v,[A.T,B.T]).T 

这是

array([[10, 9, 8, 7, 6], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 
+0

你能提供A和B的例子,看你想要什么C样的呢? –

+0

我添加了一个示例 – user3726947

回答

1

似乎是个不错的设置使用np.where基础上,做面膜的艇员选拔操作/二进制输入数据 -

C = np.where(v[:,None],B,A) 

v[:,None]部分基本上延伸到v broadcastable形状AB允许broadcasting让艇员选拔沿相应的轴的工作,axis=0在这种情况下为两个2D阵列。

采样运行 -

In [58]: A 
Out[58]: 
array([[82, 78, 57], 
     [14, 97, 32], 
     [72, 11, 49], 
     [98, 34, 41], 
     [89, 71, 52], 
     [34, 51, 55], 
     [26, 92, 59]]) 

In [59]: B 
Out[59]: 
array([[55, 67, 50], 
     [49, 64, 21], 
     [34, 18, 72], 
     [24, 61, 65], 
     [56, 59, 23], 
     [44, 77, 13], 
     [56, 55, 58]]) 

In [62]: v 
Out[62]: array([1, 0, 0, 0, 0, 1, 1]) 

In [63]: np.where(v[:,None],B,A) 
Out[63]: 
array([[55, 67, 50], 
     [14, 97, 32], 
     [72, 11, 49], 
     [98, 34, 41], 
     [89, 71, 52], 
     [44, 77, 13], 
     [56, 55, 58]]) 

如果v并不严格包括0s1s只,用v[:,None]==1np.where第一个参数。


另一种方法是用boolean-indexing -

C = A.copy() 
mask = v==1 
C[mask] = B[mask] 

注:如果v已经是一个布尔数组,跳过对1的掩模制作的比较。

运行测试 -

In [77]: A = np.random.randint(11,99,(10000,3)) 

In [78]: B = np.random.randint(11,99,(10000,3)) 

In [79]: v = np.random.rand(A.shape[0])>0.5 

In [82]: def choose_rows_copy(A, B, v): 
    ...:  C = A.copy() 
    ...:  C[v] = B[v] 
    ...:  return C 
    ...: 

In [83]: %timeit np.where(v[:,None],B,A) 
10000 loops, best of 3: 107 µs per loop 

In [84]: %timeit choose_rows_copy(A, B, v) 
1000 loops, best of 3: 226 µs per loop 
+1

感谢您的好主意。我得到了大致相同的结果基准。 – user3726947