查找满足阈值关系的组合
Finding combinations that meet a threshold relation
给定 phi
、theta
、n_1
和 n_2
的值,我需要找到所有可能的对(N_1
、N_2
) 满足以下条件:
0 <= N_1 <= n_1
0 <= N_2 <= n_2
N_1 - phi * N_2 >= theta
在 Python 中最有效的方法是什么?显然我可以使用两个 for
循环——遍历 N_1
和 N_2
的所有可能值(来自前两个标准),并只保存满足最后一个标准的那些对——但这效率很低。
这个有效:
import itertools
def _get_N_1_and_N_2(n_1, n_2, phi, theta):
"""Get the (N_1, N_2) pairs as defined in Griffith (1963).
See Equation 3.
Parameters
----------
n_1 : integer
Number of excitatory inputs.
n_2 : integer
Number of inhibitory inputs.
phi : number
Factor that captures the difference between excitatory and
inhibitory synaptic efficiencies.
theta : number
Spike threshold.
"""
N_1 = range(n_1 + 1)
N_2 = range(n_2 + 1)
possible_N_1_N_2 = itertools.product(N_1, N_2)
N_1_N_2 = []
for N_1, N_2 in possible_N_1_N_2:
if N_1 - phi * N_2 >= theta:
N_1_N_2.append((N_1, N_2))
return N_1_N_2
我想我可以用 if
语句使 for
循环成为一个非常混乱的 list
理解。但 。 . . naa.
这是测试:
import nose.tools as nt
def test__get_N_1_and_N_2():
# Figure 3A in Griffith, 1963, Biophy J.
n_1 = 4
n_2 = 0
theta = 2
phi = 1
desired = [(2, 0), (3, 0), (4, 0)]
actual = _get_N_1_and_N_2(n_1, n_2, phi, theta)
nt.assert_list_equal(desired, actual)
# Figure 3B.
n_1 = 5
n_2 = 1
theta = 2
phi = 2
desired = [(2, 0), (3, 0), (4, 0), (4, 1), (5, 0), (5, 1)]
actual = _get_N_1_and_N_2(n_1, n_2, phi, theta)
nt.assert_list_equal(desired, actual)
您可以使用 numpy 和向量化,如下所示
import numpy as np
phi = 0.5
theta = 1
n1 = 10
n2 = 20
N1 = np.random.randint(-100, 100, size=100)
N2 = np.random.randint(-100, 100, size=100)
N1 = N1[(N1 >= 0) & (N1 <= n1)]
N2 = N2[(N2 >= 0) & (N2 <= n2)]
a = N2 * theta + phi
res = N1.reshape(N1.shape[0], 1) - a.reshape(1, a.shape[0])
indices = np.argwhere(res >= 0)
pairs = zip(N1[indices[:,0]], N2[indices[:,1]])
对的示例输出
[(8, 3),
(8, 6),
(8, 5),
(8, 1),
(3, 1),
(9, 3),
(9, 8),
(9, 8),
(9, 6),
(9, 5),
(9, 6),
(9, 6),
(9, 5),
(9, 8),
(9, 1)]
根据@dbliss 的要求,这里是模块化版本及其测试
import numpy as np
def calc_combination(N1, N2, n1, n2, theta, phi):
N1 = N1[(N1 >= 0) & (N1 <= n1)]
N2 = N2[(N2 >= 0) & (N2 <= n2)]
a = N2 * theta + phi
res = N1.reshape(N1.shape[0], 1) - a.reshape(1, a.shape[0])
indices = np.argwhere(res >= 0)
pairs = zip(N1[indices[:,0]], N2[indices[:,1]])
return pairs
def test_case():
n1 = 5
n2 = 1
theta = 2
phi = 2
N1 = np.arange(n1 + 1)
N2 = np.arange(n2 + 1)
assert (calc_combination(N1, N2, n1, n2, theta, phi) ==
[(2, 0), (3, 0), (4, 0), (4, 1), (5, 0), (5, 1)])
test_case()
给定 phi
、theta
、n_1
和 n_2
的值,我需要找到所有可能的对(N_1
、N_2
) 满足以下条件:
0 <= N_1 <= n_1
0 <= N_2 <= n_2
N_1 - phi * N_2 >= theta
在 Python 中最有效的方法是什么?显然我可以使用两个 for
循环——遍历 N_1
和 N_2
的所有可能值(来自前两个标准),并只保存满足最后一个标准的那些对——但这效率很低。
这个有效:
import itertools
def _get_N_1_and_N_2(n_1, n_2, phi, theta):
"""Get the (N_1, N_2) pairs as defined in Griffith (1963).
See Equation 3.
Parameters
----------
n_1 : integer
Number of excitatory inputs.
n_2 : integer
Number of inhibitory inputs.
phi : number
Factor that captures the difference between excitatory and
inhibitory synaptic efficiencies.
theta : number
Spike threshold.
"""
N_1 = range(n_1 + 1)
N_2 = range(n_2 + 1)
possible_N_1_N_2 = itertools.product(N_1, N_2)
N_1_N_2 = []
for N_1, N_2 in possible_N_1_N_2:
if N_1 - phi * N_2 >= theta:
N_1_N_2.append((N_1, N_2))
return N_1_N_2
我想我可以用 if
语句使 for
循环成为一个非常混乱的 list
理解。但 。 . . naa.
这是测试:
import nose.tools as nt
def test__get_N_1_and_N_2():
# Figure 3A in Griffith, 1963, Biophy J.
n_1 = 4
n_2 = 0
theta = 2
phi = 1
desired = [(2, 0), (3, 0), (4, 0)]
actual = _get_N_1_and_N_2(n_1, n_2, phi, theta)
nt.assert_list_equal(desired, actual)
# Figure 3B.
n_1 = 5
n_2 = 1
theta = 2
phi = 2
desired = [(2, 0), (3, 0), (4, 0), (4, 1), (5, 0), (5, 1)]
actual = _get_N_1_and_N_2(n_1, n_2, phi, theta)
nt.assert_list_equal(desired, actual)
您可以使用 numpy 和向量化,如下所示
import numpy as np
phi = 0.5
theta = 1
n1 = 10
n2 = 20
N1 = np.random.randint(-100, 100, size=100)
N2 = np.random.randint(-100, 100, size=100)
N1 = N1[(N1 >= 0) & (N1 <= n1)]
N2 = N2[(N2 >= 0) & (N2 <= n2)]
a = N2 * theta + phi
res = N1.reshape(N1.shape[0], 1) - a.reshape(1, a.shape[0])
indices = np.argwhere(res >= 0)
pairs = zip(N1[indices[:,0]], N2[indices[:,1]])
对的示例输出
[(8, 3),
(8, 6),
(8, 5),
(8, 1),
(3, 1),
(9, 3),
(9, 8),
(9, 8),
(9, 6),
(9, 5),
(9, 6),
(9, 6),
(9, 5),
(9, 8),
(9, 1)]
根据@dbliss 的要求,这里是模块化版本及其测试
import numpy as np
def calc_combination(N1, N2, n1, n2, theta, phi):
N1 = N1[(N1 >= 0) & (N1 <= n1)]
N2 = N2[(N2 >= 0) & (N2 <= n2)]
a = N2 * theta + phi
res = N1.reshape(N1.shape[0], 1) - a.reshape(1, a.shape[0])
indices = np.argwhere(res >= 0)
pairs = zip(N1[indices[:,0]], N2[indices[:,1]])
return pairs
def test_case():
n1 = 5
n2 = 1
theta = 2
phi = 2
N1 = np.arange(n1 + 1)
N2 = np.arange(n2 + 1)
assert (calc_combination(N1, N2, n1, n2, theta, phi) ==
[(2, 0), (3, 0), (4, 0), (4, 1), (5, 0), (5, 1)])
test_case()