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]])
给定一个包含 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]])