簡體   English   中英

使用 f2py 在 Python 上進行更快的計算

[英]Using f2py for faster calculation on Python

我正在使用python進行序列對齊項目,python for循環太慢了。

所以,我決定使用f2py 我不太了解fortran,所以我堅持下面的觀點。

有兩個名為 'column' 和 'row' 的序列,其類型為np.array

例如:

column = ['A', 'T', 'G', 'C']
row = ['A', 'A', 'C', 'C'] 

我為Needleman-Wunsch算法創建了一個矩陣,並對兩個序列(列、行)進行了評分。

    import numpy as np
    column = np.array(list('ATGC'))
    row = np.array(list('AACC'))
    matrix = np.zeros((len(column) + 1, len(row) + 1), dtype='int')

    for i in range(1, len(column)+1):
        self.matrix[i][0] = -1 * i

    for j in range(1, len(row)+1):
        self.matrix[0][j] = -1 * j

    matchCheck = 0

    for i in range(1, len(column) + 1):
        for j in range(1, len(row) + 1):
            if column[i-1] == row[j-1]:
                matchCheck = 1 
            else:
                matchCheck = -1 
            top = matrix[i-1][j] + -1
            left = matrix[i][j-1] + -1
            top_left = matrix[i-1][j-1] + matchCheck
            matrix[i][j] = max(top, left, top_left)

我想從fortran獲得一些幫助以加快計算速度,所以我用fortran寫了一段代碼。

subroutine needlemanWunsch(matrix, column, row, cc, rr, new_matrix)
integer, intent(in) :: cc, rr
character, intent(in) :: column(0:cc-1), row(0:rr-1)
integer, intent(in) :: matrix(0:cc, 0:rr)
integer, intent(out) :: new_matrix(0:cc, 0:rr)
integer :: matchcheck, top, left, top_left

do i = 1, cc
    new_matrix(i, 0) = -1 * i
end do

do j = 1, rr
    new_matrix(i, 0) = -1 * j
end do

do k = 1, cc
    do l = 1, rr
        if (column(i-1).EQ.row(j-1)) then
            matchcheck = 1
        else
            matchcheck = -1 
        
        top = matrix(i-1, j) + inDel
        left = matrix(i, j-1) + inDel
        top_left = matrix(i-1, j-1) + matchCheck
        new_matrix(i, j) = max(top, left, top_left)
        end if 
    end do
end do 
return
end subroutine

然后,我用 f2py 轉換了這個 fortran 代碼,並用這個代碼將它導入到 python 中。

    import numpy as np
    column = np.array(list('ATGC'))
    row = np.array(list('AACC'))
    matrix = np.zeros((len(column) + 1, len(row) + 1), dtype='int')
    
    # import my fortran code 
    matrix = algorithm.needlemanwunsch(matrix, column, row, cc, rr)

每當我嘗試導入 Fortran 代碼時
它崩潰了...

以下在我的情況下有效。

文件neeldemanWunsch.f90

subroutine needlemanWunsch(matrix, column, row, cc, rr, new_matrix)
  integer, intent(in) :: cc, rr
  character, intent(in) :: column(0:cc-1), row(0:rr-1)
  integer, intent(in) :: matrix(0:cc, 0:rr)
  integer, intent(out) :: new_matrix(0:cc, 0:rr)
  integer :: matchcheck, top, left, top_left

  do i = 1, cc
      new_matrix(i, 0) = -1 * i
  end do

  do j = 1, rr
      new_matrix(i, 0) = -1 * j
  end do

  do k = 1, cc
      do l = 1, rr
          if (column(i-1).EQ.row(j-1)) then
              matchcheck = 1
          else
              matchcheck = -1

          top = matrix(i-1, j) + inDel
          left = matrix(i, j-1) + inDel
          top_left = matrix(i-1, j-1) + matchCheck
          new_matrix(i, j) = max(top, left, top_left)
          end if
      end do
  end do
  return
end subroutine

通過f2py編譯

$ f2py -c needlemanWunsch.f90 -m needlemanWunsch

導入python文件needlemanWunsch.py 這就是您的錯誤的來源! 您需要導入已編譯的模塊,請參見下面的示例。

import needlemanWunsch         # THIS IS MISSING IN YOUR CODE!!
import numpy as np

# create matrix
_column = ['A', 'T', 'G', 'C']
_row = ['A', 'A', 'C', 'C']
column = np.array(list(_column))
row = np.array(list(_row))
cc = len(column)
rr = len(column)
matrix = np.zeros((len(column) + 1, len(row) + 1), dtype='int')

# import my fortran code
matrix = needlemanWunsch.needlemanwunsch(matrix, column, row, cc, rr)

print(matrix)

輸出是

$ python needlemanWunsch.py 
[[ 0 -4  0  0  0]
 [-1  0  0  0  0]
 [-2  0  0  0  0]
 [-3  0  0  0  0]
 [-4  0  0  0  0]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM