poly1d 对象数组的 Numpy 问题

Numpy Problems with Arrays of poly1d Objects

我想首先从以下事实开始:在 numpy 中,可以创建 poly1d 个对象的数组:

random_poly = np.frompyfunc(lambda i, j: np.poly1d(np.random.randint(1, 4, 3)), 2, 1)
def random_poly_array(shape):    
    return np.fromfunction(random_poly, shape)

a1 = random_poly_array((3,3))

这很好用,我们甚至可以使用 np.dot:

乘以这种形式的矩阵
a2 = random_poly_array((3,3))
a1_x_a2 = np.dot(a1, a2)

但是,大多数其他方法都不起作用。例如,您不能获取某些 poly1d 对象的列表并将其转换为数组:

np.array([np.poly1d([1,2,3]), np.poly1d([1,2,3])])

因为这将提高 ValueError: cannot copy sequence with size 2 to array axis with dimension 3。雪上加霜的是,

np.array([np.poly1d([1,2]), np.poly1d([1,2])])

不会引发错误,而是创建一个仅包含 2 的 2x2 数组。添加 dtype=object 没有影响,numpy 仍会尝试将 poly1d 对象转换为数组。


之所以有问题,是因为不能将维度为 d 的数组转换为维度为 poly1d 对象的数组 d-1。我本以为

arr = np.arange(1, 10).reshape(3,3)
np.apply_along_axis(np.poly1d, 0, arr)

到 return 一个 poly1d 个对象的数组,但它 return 是一个未更改的数组。更糟糕的是,如果 arr=np.arange(9).reshape(3,3),它会抛出错误,因为创建的第一个 poly1d 对象的长度将是 2 而不是 3,因为系数为零。因此,我的问题是:是否有可行的方法在 numpy 中创建 poly1d 数组?如果不是,为什么不呢?

使用 None 强制 numpy 不将对象广播到数组中的概念,Paul Panzer 引起了我的注意,我创建了一个函数来转换最后一个轴到 poly1d 对象:

def array_to_poly(arr):
    return np.apply_along_axis(lambda poly: [None, np.poly1d(poly)], -1, arr)[..., 1]

但是,如果我们可以在一个函数中滥用多个系统,我们可以让它应用于任意轴:

def array_to_poly(arr, axis=-1):
    temp_arr = np.apply_along_axis(lambda poly: [None, np.poly1d(poly)], axis, arr)
    n = temp_arr.ndim
    s = [slice(None) if i != axis%n else 1 for i in range(n)]
    return temp_arr[s]

arr = np.arange(1, 25).reshape(2,3,4)测试,我们得到:

In [ ]: array_to_poly(arr, 0)
Out[ ]: 
array([[poly1d([ 1, 13]), poly1d([ 2, 14]), poly1d([ 3, 15]),
        poly1d([ 4, 16])],
       [poly1d([ 5, 17]), poly1d([ 6, 18]), poly1d([ 7, 19]),
        poly1d([ 8, 20])],
       [poly1d([ 9, 21]), poly1d([10, 22]), poly1d([11, 23]),
        poly1d([12, 24])]], dtype=object)

In [ ]: array_to_poly(arr, 1)
Out[ ]: 
array([[poly1d([1, 5, 9]), poly1d([ 2,  6, 10]), poly1d([ 3,  7, 11]),
        poly1d([ 4,  8, 12])],
       [poly1d([13, 17, 21]), poly1d([14, 18, 22]), poly1d([15, 19, 23]),
        poly1d([16, 20, 24])]], dtype=object)

In [ ]: array_to_poly(arr, 2)
Out[ ]: 
array([[poly1d([1, 2, 3, 4]), poly1d([5, 6, 7, 8]),
        poly1d([ 9, 10, 11, 12])],
       [poly1d([13, 14, 15, 16]), poly1d([17, 18, 19, 20]),
        poly1d([21, 22, 23, 24])]], dtype=object)

符合预期。