If you're a program maker, it's unlikely that you won't use size comparison. Among them, it is common to judge "Is the value $ c $ between $ a $ and $ b $?".
When the magnitude relationship between $ a $ and $ b $ is unknown, how do you solve the above problem?
The most sensible method is to first understand the magnitude relationship between $ a $ and $ b $, and then compare it with $ c $.
if a < b:
a < c < b
else:
b < c < a
Well, it's not very beautiful. I don't want to use 4 lines for this ...
Looking at the above, we can see that $ c $ is between $ a $ and $ b $ if either $ b <c <a $ or $ a <c <b $ holds. In other words, if you call it as follows, it will fit in one line.
(a < c < b) or (b < c < a)
It's getting better. However, this also has $ a, b, c $ appearing once, and it feels a bit redundant. You can write it so beautifully in python, but in C you have to write it as follows.
((a < c) && (c < b)) || ((b < c) && (c < a))
After all, it's not beautiful ...
So, I came up with a way to write as follows.
(a < c) ^ (b < c)
^
may not be used much, but it is an exclusive OR.
Both are True, both are False when they are False, and True when the two are True and False.
However, this has its drawbacks. The above formula is synonymous with the following.
(a < c <= b) or (b < c <= a)
This cannot be done like ʻa <c <b by changing
< to
> or
<= `.
By the way,
(a <= c) ^ (b <= c)
(a > c) ^ (b > c)
Two of
(a <= c < b) or (b <= c < a)
Is synonymous with
I wondered if I could somehow do ʻa <c <b or ʻa <= c <= b
, but I thought about it, but the following method may be the most elegant.
(a - c) * (b - c) < 0
(a - c) * (b - c) <= 0
The first line is ʻa <c <b and the second line is ʻa <= c <= b
.
If the value is large, it may be possible to take a sign function (although the calculation time is likely to be considerably slower).
I measured the calculation time of each method. The program used the following.
import time
import numpy as np
n = 100
number1 = np.random.rand(n)
number2 = np.random.rand(n)
t1 = time.time()
for j in range(10000):
for i in range(n):
if number1[i] < number2[i]:
x = number1[i] < 0.5 < number2[i]
else:
x = number1[i] < 0.5 < number2[i]
t2 = time.time()
t = t2-t1
print(t)
t1 = time.time()
for j in range(10000):
for i in range(n):
x = (number1[i] < 0.5 < number2[i]) or (number1[i] < 0.5 < number2[i])
t2 = time.time()
t = t2-t1
print(t)
t1 = time.time()
for j in range(10000):
for i in range(n):
x = (number1[i] < 0.5) ^ (number2[i] < 0.5)
t2 = time.time()
t = t2-t1
print(t)
t1 = time.time()
for j in range(10000):
for i in range(n):
x = (number1[i] - 0.5) * (number2[i] - 0.5) < 0
t2 = time.time()
t = t2-t1
print(t)
Calculation result
Method | Calculation time |
---|---|
Method 1 | 0.547s |
Method 2 | 0.458s |
Method 3 | 0.370s |
Method 4 | 0.786s |
……。
(a --c) * (b --c) <0
is the slowest result.
What is slower than Method 1 ... Isn't it just beautiful?
I tried it several times, but the ranking did not change. Well, it seems that multiplication takes time after all. Another reason is that and and or have the characteristic of ignoring subsequent operations when False or True appears in the middle.
I'm disappointed that this is all, so I also checked the calculation of the entire numpy array.
import time
import numpy as np
n = 100
number1 = np.random.rand(n)
number2 = np.random.rand(n)
t1 = time.time()
for j in range(10000):
x = ((number1 < 0.5) & ( 0.5 < number2)) | ((number1 < 0.5) & (0.5 < number2))
t2 = time.time()
t = t2-t1
print(t)
t1 = time.time()
for j in range(10000):
x = (number1 < 0.5) ^ (number2 < 0.5)
t2 = time.time()
t = t2-t1
print(t)
t1 = time.time()
for j in range(10000):
x = ((number1 - 0.5) * (number2 < 0.5) < 0)
t2 = time.time()
t = t2-t1
print(t)
You can't write ʻa <c <bin numpy. Also, since there is no and, or, it is necessary to use logical operations
&and
|`.
The calculation time is as follows.
Method | Calculation time |
---|---|
Method 2 | 0.037s |
Method 3 | 0.017s |
Method 4 | 0.031s |
In this case, the result was that multiplication was faster. I managed to keep my face ...
To determine if c is between a and b, use the following equation.
** For one-by-one comparison **
## a < c < b or b < c <In the case of a
a < c < b or b < c < a
##When a ≤ c ≤ b or b ≤ c ≤ a
a <= c <= b or b <= c <= a
## a < c ≦ b or b <When c ≤ a
(a < c) ^ (b < c)
## a ≦ c < b or b ≦ c <In the case of a
(a > c) ^ (b > c)
** For numpy arrays **
## a < c < b or b < c <In the case of a
(a - c) * (b - c) < 0
##When a ≤ c ≤ b or b ≤ c ≤ a
(a - c) * (b - c) <= 0
## a < c ≦ b or b <When c ≤ a
(a < c) ^ (b < c)
## a ≦ c < b or b ≦ c <In the case of a
(a > c) ^ (b > c)
Recommended Posts