问题
I'm working on a sequence alignment project with python, and python for loop is too slow.
So, I decided to use f2py
. I don't know much about fortran, so I'm stuck to the point below.
There are two sequence named 'column', and 'row' whose type is np.array
For example:
column = ['A', 'T', 'G', 'C']
row = ['A', 'A', 'C', 'C']
I created a matrix for the Needleman-Wunsch
algorithm, and I scored two sequences (column, row).
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)
I wanted to get some help from fortran for faster calculation, so I wrote a code with 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
Then, I converted this fortran code with f2py, and imported it on python with this code.
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)
whenever I tried to import the fortran code
it crasheds...
回答1:
The following works in my case.
File 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
Compiling it via f2py
$ f2py -c needlemanWunsch.f90 -m needlemanWunsch
Importing into python file needlemanWunsch.py
.
This is where your error comes from!
You need to import the compiled module see example below.
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)
The output is
$ 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]]
来源:https://stackoverflow.com/questions/64906784/using-f2py-for-faster-calculation-on-python