【问题标题】:Apply function to nested numpy arrays without loops将函数应用于没有循环的嵌套 numpy 数组
【发布时间】:2020-10-26 04:45:16
【问题描述】:

我正在编写遗传算法,但在避免循环方面遇到了一些问题 将交叉应用于成对的父母时。到目前为止我所拥有的很接近,但我 最后一步需要一些帮助。

人口是一个二维数组,每个个体都是一个一维数组:

pop = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])

为了得到一对父母,我使用下面的,所以父母是一个3d数组 即一对父母的数组:

inds = np.arange(pop.shape[0]).reshape((2,2))
parents = np.take(pop, inds, axis=0)
[[[ 1  2  3]
  [ 4  5  6]]
 [[ 7  8  9]
  [10 11 12]]]

现在我要执行交叉,它有签名

crossover: [parent1, parent2] -> [child1, child2]

其中 child 也是一维数组,每次交叉产生 2 个孩子

给定人口

[p1
 p2
 p3
 p4]

我想回来

[crossover(p1,p2)[0]
 crossover(p1,p2)[1]
 crossover(p3,p4)[0]
 crossover(p3,p4)[1]]

或者,因为它可以简单地展平

[crossover(p1,p2)
 crossover(p3,p4)]

我尝试使用np.apply_along_axis,但我认为无法使用它 适用于一对父母,一次只有一个父母(使用axis=-1)。

谁能建议任何 numpy 唯一的方法来做到这一点?

其他信息 - 这是我目前正在做的方式,带有列表组合:

children = [
        crossover(pop[2 * i], pop[2 * i + 1])
        for i in range(pop.shape[0] // 2)
]

【问题讨论】:

  • 预期的 o/p 是多少?
  • apply_along_axis 只是一个方便的迭代器,在处理 3d 数组时最有用。它不是速度工具。它不会编译您的函数。如果您不知道如何重写 crossover 以使用整个数组,我建议您使用索引进行明显的迭代。
  • 嗨@Divakar - o/p 是输出吗?我将添加更多信息。
  • @hpaulj 感谢您的评论。我知道这不是为了速度。但我正在尝试学习 numpy,以及如何使用使编码更容易的函数:)

标签: numpy


【解决方案1】:

好的,我设法让它工作,即使这意味着改变我的分频功能。 通过重塑 pop 数组,您可以连接连续的行。

pop = np.array([[0,1,5,6,7,2,3,4],[0,7,2,6,1,5,4,3],[2,5,1,7,0,3,4,6],[7,6,5,1,2,0,4,3]])
pop_resh = pop.reshape((pop.shape[0]//2, -1))

[[0 1 5 6 7 2 3 4]
 [0 7 2 6 1 5 4 3]
 [2 5 1 7 0 3 4 6]
 [7 6 5 1 2 0 4 3]]

[[0 1 5 6 7 2 3 4 0 7 2 6 1 5 4 3]
 [2 5 1 7 0 3 4 6 7 6 5 1 2 0 4 3]]

现在 apply_along_axis 可以用于每对组合的行,然后重新调整形状以恢复初始形状。

children = np.apply_along_axis(py_crossover, 1, pop_resh).reshape(pop.shape)

[[0 7 6 1 5 2 3 4]
 [0 1 6 7 2 5 4 3]
 [6 5 1 7 0 2 4 3]
 [7 6 5 1 2 0 3 4]]

我不确定我是否会使用它,或者只是坚持使用列表组合的方式,但这个解决方案至少可以帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 2021-01-04
    • 1970-01-01
    • 2018-08-20
    • 2012-04-27
    相关资源
    最近更新 更多