2013-05-08 42 views
1

我有一个数组,并希望基于使用另一个数组的分类更改元素。这就是说,我导入一个数组,然后如果cell [i,j]的值在一定范围内(比如1和8之间),那么将secondArray [i,j]乘以0.3,并将结果放入我有一些代码这样做(也许解释我的意思是更清楚一点),但它需要很长的时间(因为我的数组是1000 * 1000左右元素),并想知道是否有更有效的解决方案。Python数组,有条件地更改分类上的元素

目前我有:

.. 
import numpy as np 

def Factor_AM(cell):    
    if cell < 1  return 0.2; 
    elif cell < 8:  return 0.3; 
    else:  return 0.5; 



mat = np.array(..some code to get an array from an external source..) //size 1000*1000 
mat_out_1 = np.zeros_like(mat) 
mat_out_1 = np.zeros_like(mat) 

mat_ClassifyMe = np.array(..some code to import another 1000*1000 array with values in) 

for index, x in np.ndenumerate(mat): 
    mat_out_1[index] = Factor_AM(x) * mat_ClassifyMe[index] 
    mat_out_2[index] = (1-Factor_AM(x)) * mat_ClassifyMe[index] 

..some code to output mat_out_1 and mat_out_2 

我看到np.where和看起来希望np.argwhere功能的一些文档,但考虑到我有超过1个测试(在上面的代码中,我有3个,但在现实中,我有12)我不能想出一个方式,没有做出非常丑陋的嵌套语句。

是否有另一种方式来做到这一点,或者这是否像Python那样高效?

回答

1

您可以使用Boolean or “mask” index arrays用于此目的,例如:

import numpy as np 

mat = np.arange(16.0).reshape((4,4)) 

mat_out = np.zeros_like(mat) 

mat_out[mat < 6] = 0.2 * mat[mat < 6] # using a conditional for indexing 
# or use a variable for the boolean 'masking' index array 
mask1 = np.logical_and(mat >= 6, mat < 10) 
mat_out[mask1] = 0.3 * mat[mask1] 
mask2 = mat >= 10 
mat_out[mask2] = 0.5 * mat[mask2] 

print mat 
print mat < 6 
print mask1 
print mat_out 
+0

感谢,看起来像我需要什么。 我将通过一些计时器来运行代码,以了解它们之间的区别。 – CastleH 2013-05-08 11:29:40

+0

时间结果: 内循环(即减去开销用于访问和outputing阵列等节目,只看矩阵过滤) 〜25秒到0.5秒〜 鉴于我在做这几百倍,这是一个非常有意义的速度增加。干杯。 – CastleH 2013-05-08 20:27:39

0
mat = np.array([0.1, 0.2, 5, 4, 9, 0.05, 2, 11]) # an example of input #1 
mat_ClassifyMe = np.ones_like(mat) # an example of input #2 
mask1 = mat < 1 
mask2 = mat >= 8 
f = np.empty_like(mat) 
f[mask1] = 0.2 
f[mask2] = 0.5 
f[np.logical_not(mask1 | mask2)] = 0.3 
mat_out_1 = f * mat_ClassifyMe 
mat_out_2 = (1 - f) * mat_ClassifyMe