Кто-нибудь видит какой-нибудь способ разрезать это? (python) - PullRequest
0 голосов
/ 04 августа 2020

Я пытался ускорить некоторые массивы numpy в Python, и я знаю, что циклы for действительно плохи, поэтому вам следует их разрезать, но я просто не вижу возможности разрезать это. Может есть какая-то хитрость? Я довольно неопытен в этом, поэтому был бы признателен за любую помощь!

    def propind(in1, in2):
        return in1+M*in2
     
    for ind1 in range(M):
        for ind2 in range(N):
            for ind3 in range(M):
                for ind4 in range(N):
                    ret[propind(ind1,ind2), propind(ind3,ind4)] = tempH0s[ind1,ind2,ind4]*(ind1==ind3)

tempH0s - это матрица MxNxN, а ret - это матрица (MxN) x (MxN).

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Я пробовал что-то вроде

ret = np.zeros((M,N,M,N))
ind = np.arange(M)
ret[ind,:,ind,:] = tempH0s[ind,:,:]
ret = ret.reshape(M*N, M*N)

, но расположение значений отличалось от того, что делает ваша итерация. Я подозреваю, что отображение in1+M*in2 является частью разницы.

Если разницу можно устранить, это должно быть немного быстрее.

In [93]: tempH0s                                                                                     
Out[93]: 
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]]])

ваша итерация дает

In [87]: foo(tempH0s,2,3)                                                                            
Out[87]: 
array([[ 0,  1,  0,  0,  0,  0],
       [ 3,  4,  0,  0,  0,  0],
       [ 0,  0,  9, 10, 11,  0],
       [ 0,  0, 12, 13, 14,  0],
       [ 0,  0, 15, 16, 17,  0],
       [ 0,  0,  0,  0,  0,  0]])

, где, как я предлагаю, дает:

array([[ 0,  1,  2,  0,  0,  0],
       [ 3,  4,  5,  0,  0,  0],
       [ 6,  7,  8,  0,  0,  0],
       [ 0,  0,  0,  9, 10, 11],
       [ 0,  0,  0, 12, 13, 14],
       [ 0,  0,  0, 15, 16, 17]])

Ваш другой код дает

array([[ 0.,  0.,  1.,  0.,  2.,  0.],
       [ 0.,  9.,  0., 10.,  0., 11.],
       [ 3.,  0.,  4.,  0.,  5.,  0.],
       [ 0., 12.,  0., 13.,  0., 14.],
       [ 6.,  0.,  7.,  0.,  8.,  0.],
       [ 0., 15.,  0., 16.,  0., 17.]])
1 голос
/ 04 августа 2020

Просто хотел дать решение, которое я получил, используя комментарии к этому вопросу. Это примерно в 20 раз быстрее, так что спасибо!

tempH0s2 = []

for z in range(M):
    tempL = np.zeros([M,N,N])
    tempL[z] = 1
    tempH0s2.append(tempH0s*tempL)

tempH0s3 = np.stack(tempH0s2, axis=2)

ret = np.reshape(tempH0s3, (M*N, M*N), order='F')
...