继承自 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 示例以获取完整的两个点交叉。
比较个体¶
当想要使用 HallOfFame
或 ParetoFront
名人堂时。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.array
比 array.array
更长。
你不需要知道什么¶
创建者系统性地替换了 numpy.ndarray
的几个基本功能,以便
数组实例可以从一个可迭代对象创建;
它深度复制了对象
__dict__
中添加的属性;pickling 包括属性的字典。
更多详情请参见 creator
模块中 _numpy_array
的实现。