1 回答
TA贡献1796条经验 获得超4个赞
当您使用 NumPy 数组时,我将尝试在部分中解决这个问题,就好像它们是列表一样,因此首先失去了库的很多目的。尽管语法更加紧凑,但它带来了显着的速度提升。
创造人口
这个很简单。我们可以直接替换生成pop
使用numpy.random.randint
。我们需要为 和 指定值population_size
并chromosome length
使用这些值来指定输出大小。
population_size = 6 chromosome_length = 10 pop = np.random.randint(0, 2, (population_size, chromosome_length))
注意:这不会给出与您在实际问题中包含的完全相同的值,因为我们没有为随机数生成器设置种子。但是,代码直接等效于您的for
循环,但性能更高。
生成expected
我无法准确替换本节,因为替换你的循环太多了,一些变量也未定义。所以,我只是假设我将获得与您显示的相同的二维数组:
expected = np.array([[1.99214608], [1.45140389], [0.07068525], [0.69507167], [1.08384057], [0.70685254]])
分箱数据
这有点复杂。我们可以利用numpy.digitize
在您的区间(0、0.9 和 1.5)之间对数据进行分类。但是,此方法不适用于 2D 数组,因此我将首先使用numpy.ravel()
展平数组。
这将返回每个值expected
所属的 bin 标识列表。但是,bin 标识从 1 开始,我们希望将这些值用作数组的索引,因此我还将同时从结果中减去 1。
bins = np.array([0, 0.9, 1.5]) dig = np.digitize(expected.ravel(), bins) - 1
最后的步骤
我将创建一个与 bin 类别相对应的值数组。然后我们可以使用相应的替换值numpy.take
来替换 的值。dig
replacements = np.array([0, 1, 2]) actual = np.take(replacements, dig)
最后:),我们可以使用numpy.repeat
usingactual
以正确的比例获取行pop
来构建输出。
最终代码
import numpy as np
population_size = 6
chromosome_length = 10
pop = np.random.randint(0, 2, (population_size, chromosome_length))
# But I'm going to deliberately overwrite the above to solve your particular case
pop = np.array([[0., 1., 0., 1., 1., 1., 0., 0., 1., 1.],
[0., 0., 1., 0., 1., 0., 1., 1., 0., 0.],
[0., 0., 1., 0., 0., 1., 1., 0., 0., 1.],
[0., 0., 0., 0., 1., 0., 1., 1., 1., 0.],
[0., 0., 0., 0., 1., 0., 1., 1., 0., 1.],
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]])
# Hard-coded :/
expected = np.array([[1.99214608],
[1.45140389],
[0.07068525],
[0.69507167],
[1.08384057],
[0.70685254]])
bins = np.array([0, 0.9, 1.5])
dig = np.digitize(expected.ravel(), bins) - 1
replacements = np.array([0, 1, 2])
actual = np.take(replacements, dig)
out = np.repeat(pop, actual, axis=0)
print(out)
给出:
[[0. 1. 0. 1. 1. 1. 0. 0. 1. 1.]
[0. 1. 0. 1. 1. 1. 0. 0. 1. 1.]
[0. 0. 1. 0. 1. 0. 1. 1. 0. 0.]
[0. 0. 0. 0. 1. 0. 1. 1. 0. 1.]]
添加回答
举报