关于python:多个numpy数组上的多步线性代数运算

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')

在这里,我使用的(3000, 3000)阵列。在我的机器,而不使用NumPy 0.47秒使用一numba 0.29秒。


单将使用布尔图

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让很多的作业。那里有个更多的最佳方法。