我制作了这个生成器,它运行完美。
# - Function generator
def polyF(matrix, i=1):
if i == 1: yield np.c_[np.ones(matrix.shape[0]), matrix]; i+=1
while i > 1:
matrix = np.hstack((matrix, matrix[:, 0:1]**i))
i+=1
yield np.c_[np.ones(matrix.shape[0]), matrix]
但是它看起来并不美观。所以我尝试了类似的方法,但是它根本不起作用,我想知道为什么这不起作用。
# - Function generator
def polyF(matrix, i=1):
while i > 1:
matrix = np.hstack((matrix, matrix[:, 0:1]**i))
i+=1
yield np.c_[np.ones(matrix.shape[0]), matrix]
yield np.c_[np.ones(matrix.shape[0]), matrix]; i+=1
getP = polyF(X)
当我使用next(getP)时,这是我收到的错误消息。
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-15-91b0148b3536> in <module>()
25
26 # - Predicting yP
---> 27 X_ = next(getP)
28 W = np.linalg.inv( X_.T @ X_ ) @ X_.T @ Y
29 yP = W @ X_.T
StopIteration:
发生了什么事?
因为我想帮助您使代码实际上如您所说的那样“美观”,并且因为我了解到我实际上不能依靠codereview.stackexchange.com对这种事情有所帮助,所以这是我的尝试。
首先,我们注意到在循环内,i += 1
可以移到yield
之后,因为它不会影响yield
中的表达式。然后,重复这两行(我将; i+= 1
分隔为单独的行):
def polyF(matrix, i=1):
if i == 1:
yield np.c_[np.ones(matrix.shape[0]), matrix] # A
i+=1 # B
while i > 1:
matrix = np.hstack((matrix, matrix[:, 0:1]**i))
yield np.c_[np.ones(matrix.shape[0]), matrix] # A
i+=1 # B
因此,我们可以通过首先将循环边界设置为包括1
,然后在hstack
时将i == 1
步骤设置为除外],让循环处理此问题:
def polyF(matrix, i=1): while i > 0: if i != 1: matrix = np.hstack((matrix, matrix[:, 0:1]**i)) yield np.c_[np.ones(matrix.shape[0]), matrix] i+=1
[接下来,我注意到
while
条件旨在对严格为正的i
无限循环,而对于零或为负的i
不执行任何操作。后者似乎是一种特例,我想明确地处理它。这也使我可以使用标准库来处理i
的“计数”逻辑:
import itertools
def polyF(matrix, i=1):
if i < 1:
return # but maybe we should raise an exception instead?
for degree in itertools.count(i):
if degree != 1:
matrix = np.hstack((matrix, matrix[:, 0:1]**degree))
yield np.c_[np.ones(matrix.shape[0]), matrix]