未来警告:要堆叠的数组 可迭代解包列表理解列表构造器

问题描述

当我尝试使用以下功能时:

x_bounds = np.array([[   1.,100.],[ 0.01,1.],[   0.,1.]]) 

def generate_x_mesh ():
    X = np.meshgrid( np.linspace(*x_bounds[0],num=20),# x_1
                     np.linspace(*x_bounds[1],# x_2
                     [0,1])                              # x_3
    return np.vstack(map(np.ravel,X)).T

def training_data (model):
    Xsim = generate_x_mesh()
    Xsim = np.vstack( (Xsim,Xsim))

我收到以下错误

C:\ProgramData\Anaconda3\lib\site-packages\ipykernel_launcher.py:5:FutureWarning:堆栈的数组必须作为“序列”类型传递,例如列表或元组。从 NumPy 1.16 开始,不推荐使用对非序列迭代器(例如生成器)的支持,并且将来会引发错误

解决方法

@Ch3steR 在评论中解决了这个问题,这个答案只是为已经很好的答案提供了一些背景。

问题

map(np.ravel,X) 给出一个生成器对象,而不是像列表或元组这样的序列对象。区别并非微不足道,一些过去接受生成器的函数将来可能会删除该功能。这就是这里发生的事情。

解决方案

我们可以解包生成器对象将产生的所有内容,然后将其放入列表中。有几种方法可以做到这一点。

可迭代解包

这是自 PEP 448 以来最简洁的方法。它接受一个可迭代对象(例如生成器)并将其解包为一个序列。您将列表用作 np.vstack 的参数,因此这确实需要方括号,但在某些情况下您可以省略它们。

[*map(np.ravel,X)]

很简单,但还有其他方法可以让其他(或新的)程序员更清楚代码,例如...

列表理解

List comprehension 已经存在一段时间了,它是一种巧妙的表示法,它使用 for 循环迭代某些内容并将结果放入列表中。

[np.ravel(i) for i in X]

这通过使用符号迭代生成器,直到它没有更多的对象,这可能看起来比上面的可迭代解包符号更清晰。 for ... in 表示法应该对大多数(如果不是全部)程序员都很熟悉,而方括号则提示您这将在列表中。

还有另一种可能更清晰的方法......

列表构造器

这种方法可能是最能表达意图的方式。您有一个想要转换为列表的生成器,您可以从中构建一个列表。

list(map(np.ravel,X))

这是有效的,因为您将一个可迭代对象作为 list constructor 的唯一参数传递。构造函数将解压该生成器并返回一个列表。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...