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)
符合预期。
我想首先从以下事实开始:在 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)
符合预期。