继承自 Numpy

DEAP 的 creator 允许继承自 numpy.ndarray,从而使个体能够拥有强大的 Numpy 库的属性。与其他任何基类一样,继承自 numpy.ndarray 并不比将其作为基类更复杂。:

import numpy
from deap import base, creator
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)

你应该关注什么!

继承自 numpy.ndarray 是一个吸引人的特性,但在数据的有效性和系统性能方面需要特别注意。

复制与切片

numpy.ndarray 进行切片时应小心。返回的元素是原始对象的 numpy.ndarray.view()。当从一个数组交换数据到另一个数组时,这会导致容易出错的代码。例如,两点交叉使用以下方法在两个列表之间交换数据。:

>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> a[1:3], b[1:3] = b[1:3], a[1:3]
>>> print(a)
[1, 6, 7, 4]
>>> print(b)
[5, 2, 3, 8]

使用 numpy.array,同样的操作会导致单个结果个体被改变。:

>>> import numpy
>>> a = numpy.array([1,2,3,4])
>>> b = numpy.array([5,6,7,8])
>>> a[1:3], b[1:3] = b[1:3], a[1:3]
>>> print(a)
[1 6 7 4]
>>> print(b)
[5 6 7 8]

问题是,首先,a 中的元素被 b 返回的视图中的元素替换,而 b 中的元素被 a 视图中的元素替换,这些元素现在是初始在 b 中的元素,导致最终结果错误。解决这个问题的一种方法是显式地复制 __getitem__ 返回的视图。:

>>> import numpy
>>> a = numpy.array([1,2,3,4])
>>> b = numpy.array([5,6,7,8])
>>> a[1:3], b[1:3] = b[1:3].copy(), a[1:3].copy()
>>> print(a)
[1 6 7 4]
>>> print(b)
[5 2 3 8]

因此,在继承自 numpy.ndarray 时必须小心;tools 模块中的 没有 运算符实现这种复制。请参阅 Numpy 的 One Max 示例以获取完整的两个点交叉。

比较个体

当想要使用 HallOfFameParetoFront 名人堂时。similar 函数应更改为比较所有函数。使用常规的 operator.eq() 函数将导致一个比较向量

>>> a = numpy.array([1, 2, 3])
>>> b = numpy.array([1, 2, 3])
>>> operator.eq(a, b)
array([ True,  True,  True], dtype=bool)

这不能用作条件

>>> if operator.eq(a, b):
...     print "Gosh!"
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

必须将 similar 操作符替换为类似 numpy.array_equal()numpy.allclose() 的 numpy 函数。:

hof = tools.HallOfFame(1, similar=numpy.array_equal)

现在可以计算条件,名人堂将会很高兴。

>>> if numpy.array_equal(a, b):
...     print "Yeah!"
"Yeah!"

性能

如果你的目标是性能,DEAP Speed 显示使用 array.array 应该优于 numpy.ndarray。这主要是因为创建(深度复制也需要)新数组的时间对于 numpy.arrayarray.array 更长。

你不需要知道什么

创建者系统性地替换了 numpy.ndarray 的几个基本功能,以便

  • 数组实例可以从一个可迭代对象创建;

  • 它深度复制了对象 __dict__ 中添加的属性;

  • pickling 包括属性的字典。

更多详情请参见 creator 模块中 _numpy_array 的实现。