Multi-step linear algebra operations on multiple numpy arrays
有3 numpy阵列:
1 2 3 4 | import numpy arr_a = numpy.random.random((300, 300)) arr_b = numpy.random.random((300, 300)) arr_c = numpy.random.random((300, 300)) |
我想创建一个阵列(4个_ D)从一个组合的3阵列。游戏规则是:AA follows
如果_ ARR值>网格细胞A和B _ 0.2 ARR值<0.4和0.6个_然后填充C、D与1个_
如果_ ARR值>网格细胞A和B _ 0.3 ARR值<0.5和0.6个_然后填充C、D与2个_
如果_ ARR值>网格细胞A和B _ 0.1 ARR值<0.2和0.5个_然后填充C、D与3个_
在所有其他情况_ fill ARR D与4
这样做可以使用嵌套的循环,但这是极慢、不甚语言.也,这是一个测试案例,是真正的阵列尺寸1000×1000,所以我想要一个scaleable preferably parallizable溶液。
使用纯Python的for循环和一个步行的路要走。你可以写你的程序中使用阵列的有效运作在NumPy做循环,加速enormously的C代码。然而,在整个新的阵列中的每个实例化的规则,每一个相同的尺寸为您的数据。你可以使用什么样numba代替,这是一个如PythonPython分发。你可以写你的代码的一个numba使用循环,但没有时间的刑罚(它compiles代码到本地机器指令)。因此,没有额外的大型阵列的制作人员都需要更多的内存,它的效率比NumPy。numba所以发生的更快,本节目为例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import numpy, numba, time def using_numpy(shape): arr_a = numpy.random.random(shape) arr_b = numpy.random.random(shape) arr_c = numpy.random.random(shape) mask1 = numpy.logical_and(numpy.logical_and((arr_a > 0.2), (arr_b < 0.4)), (arr_c > 0.6)) mask2 = numpy.logical_and(numpy.logical_and((arr_a > 0.3), (arr_b < 0.5)), (arr_c > 0.6)) mask3 = numpy.logical_and(numpy.logical_and((arr_a > 0.1), (arr_b < 0.2)), (arr_c > 0.5)) result = numpy.ones(arr_a.shape)*4 result[mask1] = 1 result[mask2] = 2 result[mask3] = 3 return result @numba.jit def using_numba(shape): arr_a = numpy.random.random(shape) arr_b = numpy.random.random(shape) arr_c = numpy.random.random(shape) result = numpy.empty(shape) for i in range(result.shape[0]): for j in range(result.shape[1]): if arr_a[i, j] > 0.2 and arr_b[i, j] < 0.4 and arr_c[i, j] > 0.6: result[i, j] = 1 elif arr_a[i, j] > 0.3 and arr_b[i, j] < 0.5 and arr_c[i, j] > 0.6: result[i, j] = 2 elif arr_a[i, j] > 0.1 and arr_b[i, j] < 0.2 and arr_c[i, j] > 0.5: result[i, j] = 3 else: result[i, j] = 4 return result # Compile the using_numba function using_numba((0, 0)) t0 = time.time() result = using_numpy((3000, 3000)) print('NumPy took', time.time() - t0, 'seconds') t0 = time.time() result = using_numba((3000, 3000)) print('Numba took', time.time() - t0, 'seconds') |
在这里,我使用的
单将使用布尔图
1 2 3 4 5 6 7 | condition_1 = numpy.logical_and(numpy.logical_and((arr_a > 0.2), (arr_b < 0.4)), (arr_c > 0.6)) condition_2 = numpy.logical_and(numpy.logical_and((arr_a > 0.3), (arr_b < 0.5)), (arr_c > 0.6)) condition_3 = numpy.logical_and(numpy.logical_and((arr_a > 0.1), (arr_b < 0.2)), (arr_c > 0.5)) result = numpy.ones((300, 300)) * 4 result[numpy.where(condition_3)] = 3 result[numpy.where(condition_2)] = 2 result[numpy.where(condition_1)] = 1 |
它避免了循环嵌套,但allocates专用阵列和三superfluous让很多的作业。那里有个更多的最佳方法。