Python 从基础数组创建多个数组

Python creating multiple array from a basis array

给定一个包含 n 个元素的数组 [x1 x2 x3 ... xn],需要生成包含 K 行的以下数组:

[[x1   x2   x3   ... xn],
 [x1^2 x2^2 x3^2 ... xn^2],
 [x1^3 x2^3 x3^3 ... xn^3],
 ...,
 [x1^K x2^K x3^K ... xn^K]].

如何有效地得到这个?

您可以使用 numpy.power.outer:

>>> K=9
>>> numpy.power.outer(numpy.array([1, 4, 5]), numpy.arange(1, K+1)).T
array([[      1,       4,       5],
       [      1,      16,      25],
       [      1,      64,     125],
       [      1,     256,     625],
       [      1,    1024,    3125],
       [      1,    4096,   15625],
       [      1,   16384,   78125],
       [      1,   65536,  390625],
       [      1,  262144, 1953125]])

您正在查看时间复杂度为 O(kn) 的算法:

def build_value_lists(base_numbers, max_exponent):
    value_lists = []
    for k in range(1, max_exponent+1):
        values = []
        for x in base_numbers:
            values.append(x**k)
        value_lists.append(values)

    return value_lists

base_numbers = [1, 2, 3, 4, 5];
max_exponent = 3

print build_value_lists(base_numbers, max_exponent)

由于您需要一个包含所有值的 Python 列表,因此很难使该算法更加高效。如果您只是想让代码 运行 更快,请注意线程不太可能提高性能。 Multiprocessing 将是您最好的选择。这个想法是创建一个工人池,每个工人计算一个列表的一个值 k 的结果。当每个工作人员完成其任务时,结果可以附加到包含列表中。

您可以使用PolynomialFeatures

测试栏目:

import numpy as np
col = np.linspace(1, 5, 5).reshape((-1, 1))

变换:

from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(degree=4, include_bias=False)
poly.fit_transform(col).T

> array([[  1.,   2.,   3.,   4.,   5.],
         [  1.,   4.,   9.,  16.,  25.],
         [  1.,   8.,  27.,  64., 125.],
         [  1.,  16.,  81., 256., 625.]])

使用 ** 运算符和广播的 power.outer 变体:

In [223]: np.arange(1,5)**np.arange(1,4)[:,None]                                
Out[223]: 
array([[ 1,  2,  3,  4],
       [ 1,  4,  9, 16],
       [ 1,  8, 27, 64]])

您可以制作一个矩阵,将数组重复 K 次,然后使用 numpy 的 cumprod()

result = np.cumprod([arr,]*k,axis=0)

如果您不使用 numpy,常规 python 列表可以使用 itertools 中的 accumulate 来做同样的事情。

result = accumulate( ([arr]*k), func=lambda a,b: [x*y for x,y in zip(a,b)])

虽然这会比使用 numpy 慢很多。

注意:累积returns一个迭代器,你可以用list(result)

把它变回一个列表

这是一个非常有名的矩阵,叫做Vandermonde matrix。 Numpy包中有一个特殊的函数来获取这个矩阵:

import numpy as np 
np.fliplr(np.vander([2,3,4], 5)).T


> array([[  1,   1,   1],
       [  2,   3,   4],
       [  4,   9,  16],
       [  8,  27,  64],
       [ 16,  81, 256]])