poly1d对象数组的Numpy问题

时间:2017-12-03 21:52:48

标签: python arrays numpy polynomials

我想首先开始讨论这样一个事实: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 的数组并将其转换为维度 d-1 poly1d对象数组>。我原以为

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

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

1 个答案:

答案 0 :(得分:1)

使用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)

正如所料。