如果将不等式乘以负数,则必须反转不等式的方向。
例如:
如果x = 6,则与等式(1)和(2)一致。
有没有办法将不等式语句乘以Python的单行中的整数来反转符号?
从实际角度来看,我试图从TBLASTN结果中提取DNA /蛋白质序列。有股+1和-1,并且该条件语句之后的操作是相同的。
# one-liner statement I would like to implement
if (start_codon <= coord <= stop_codon)*strand:
# do operation
# two-liner statement I know would work
if (start_codon <= coord <= stop_codon) and strand==1:
# do operation
elif (start_codon >= coord >= stop_codon) and strand==-1:
# do operation
答案 0 :(得分:5)
您可以根据strand
值选择下限和上限。这假定strand
始终为1
或-1
,并使用bool
作为Python中的int
子类,以便True
和{ {1}}可用于索引成对:
False
答案 1 :(得分:4)
你写得像:
if (start_codon <= coord <= stop_codon) and strand==1:
# do operation
elif (start_codon >= coord >= stop_codon) and strand==-1:
# do operation
但这相当于:
if abs(strand) == 1 and strand * start_codon <= strand * coord <= strand * stop_codon:
# do operation
pass
或者我们可以假设abs(strand) == 1
始终成立:
if strand * start_codon <= strand * coord <= strand * stop_codon:
# do operation
pass
这是有效的,因为 x >= y
与-x <= -y
相等。因此,而不是&#34;倒转&#34;条件,我们将两个操作数乘以-1
,因此隐式反转条件。让我们举个例子:
如果strand == 1
,那么我们会评估-start_codon <= -coord <= -stop_codon
。这相当于-start_codon <= -coord and -coord <= -stop_codon
。现在我们可以使用start_codon >= coord and coord >= stop_codon
来标准化两个子表达式,这相当于start_codon >= coord coord >= stop_codon
。这意味着 -start_codon <= -coord <= -stop_codon
相当于start_codon >= coord >= stop_codon
。
我们做出一个假设:那就是start_codon
和stop_codon
是数字(这样我们可以将它们相乘)。
我们可以通过以下设置在经验上产生这种关系的经验证据:
import numpy as np
test_size = 1000
a = np.random.randn(test_size, 4) # generate 1000x4 matrix of random data
a[:,3] = np.sign(a[:,3]) # make the last column -1 and 1
assert not (a[:,3] == 0).any() # check no zeros in the last column
b = np.zeros(test_size) # results for our relation
c = np.zeros(test_size) # results for the question implementation
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
b[i] = strand * start_codon <= strand * coord <= strand * stop_codon
if (start_codon <= coord <= stop_codon) and strand==1:
c[i] = 1
elif (start_codon >= coord >= stop_codon) and strand==-1:
c[i] = 1
else:
c[i] = 0
assert (b == c).all()
如果我们采用上述代码,我们可以轻松修改它以检查性能如下:
import numpy as np
from operator import ge, le
test_size = 100000
a = np.random.randn(test_size, 4) # generate 1000x4 matrix of random data
a[:,3] = np.sign(a[:,3]) # make the last column -1 and 1
assert not (a[:,3] == 0).any() # check no zeros in the last column
b = np.zeros(test_size) # target array
def code_kevin():
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
if (start_codon <= coord <= stop_codon) and strand==1:
b[i] = 1
elif (start_codon >= coord >= stop_codon) and strand==-1:
b[i] = 1
def code_schwo():
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
cdns = (start_codon, stop_codon)
if (cdns[strand==-1] <= coord <= cdns[strand==1]):
b[i] = 1
def code_moinu():
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
codon_check = (le, ge)[strand==1]
if codon_check(start_codon, coord) and codon_check(coord, stop_codon):
b[i] = 1
def code_wille():
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
if strand * start_codon <= strand * coord <= strand * stop_codon:
b[i] = 1
def code_fabio():
for i, (start_codon, coord, stop_codon, strand) in enumerate(a):
if pow(start_codon/coord, strand) <= 1 <= pow(stop_codon/coord, strand):
b[i] = 1
作为操作,我们使用b[i] = 1
。此外,我们总是使用if
语句(而不是直接分配布尔值)来使比较时间更公平。
然后我们可以使用timeit.timeit
,多次运行每个函数,并计算所需的秒数:
>>> timeit.timeit(code_kevin, number=100)
8.667507636011578
>>> timeit.timeit(code_schwo, number=100)
10.56048975896556
>>> timeit.timeit(code_wille, number=100)
8.908266504004132
>>> timeit.timeit(code_fabio, number=100)
13.454442486981861
>>> timeit.timeit(code_moinu, number=100)
10.350756354047917
答案 2 :(得分:1)
您可以使用简单的数学:
<TextBlock>
<Run />
<Run />
</TextBlock>
因为x ^ -1使比率事实上的反转反转了比较方向
答案 3 :(得分:1)