我有一个很大的长度 t ( t = 200K行)
价格= [200,100,500,300 ..]
,我想计算一个矩阵( t X t ),其中值的计算方式为:
matrix[i][j] = prices[j]/prices[i] - 1
我尝试使用double进行此操作,但速度太慢。有什么想法可以更好地执行它吗?
for p0 in prices:
for p1 in prices:
matrix[i][j] = p1/p0 - 1
答案 0 :(得分:2)
向量化解决方案使用np.meshgrid
,并以prices
和1/prices
作为参数(请注意,价格必须是数组),然后将结果相乘并减去1
为了计算matrix[i][j] = prices[j]/prices[i] - 1
:
a, b = np.meshgrid(p, 1/p)
a * b - 1
例如:
p = np.array([1,4,2])
会给:
a, b = np.meshgrid(p, 1/p)
a * b - 1
array([[ 0. , 3. , 1. ],
[-0.75, 0. , -0.5 ],
[-0.5 , 1. , 0. ]])
快速检查一些单元格:
(i,j) prices[j]/prices[i] - 1
--------------------------------
(1,1) 1/1 - 1 = 0
(1,2) 4/1 - 1 = 3
(1,3) 2/1 - 1 = 1
(2,1) 1/4 - 1 = -0.75
另一种解决方案:
[p] / np.array([p]).T - 1
array([[ 0. , 3. , 1. ],
[-0.75, 0. , -0.5 ],
[-0.5 , 1. , 0. ]])
答案 1 :(得分:1)
我想可以用这种方式完成
import numpy
prices = [200., 300., 100., 500., 600.]
x = numpy.array(prices).reshape(1, len(prices))
matrix = (1/x.T) * x - 1
让我详细解释。该矩阵是逐元素价格值的列向量和原始价格值的行向量的矩阵乘积。然后需要从结果中减去相同大小的矩阵。 首先,我们从价格清单创建行向量
x = numpy.array(prices).reshape(1, len(prices))
此处需要重塑。否则,向量将具有形状(len(prices),)
,而不是(1, len(prices))
。
然后,我们计算元素价格倒数价格的列向量:
(1/x.T)
最后,我们计算出结果矩阵
matrix = (1/x.T) * x - 1
此处结尾的- 1
将被广播到与(1/x.T) * x
相同形状的矩阵中。
答案 2 :(得分:1)
有两种惯用的方式来执行外部产品类型的操作。可以使用通用函数的.outer
方法,在此处np.divide
:
In [2]: p = np.array([10, 20, 30, 40])
In [3]: np.divide.outer(p, p)
Out[3]:
array([[ 1. , 0.5 , 0.33333333, 0.25 ],
[ 2. , 1. , 0.66666667, 0.5 ],
[ 3. , 1.5 , 1. , 0.75 ],
[ 4. , 2. , 1.33333333, 1. ]])
或者,使用广播:
In [4]: p[:, None] / p[None, :]
Out[4]:
array([[ 1. , 0.5 , 0.33333333, 0.25 ],
[ 2. , 1. , 0.66666667, 0.5 ],
[ 3. , 1.5 , 1. , 0.75 ],
[ 4. , 2. , 1.33333333, 1. ]])
此p[None, :]
本身可以拼写为重塑p.reshape((1, len(p)))
,但可读性强。
两者都等同于double for循环:
In [6]: o = np.empty((len(p), len(p)))
In [7]: for i in range(len(p)):
...: for j in range(len(p)):
...: o[i, j] = p[i] / p[j]
...:
In [8]: o
Out[8]:
array([[ 1. , 0.5 , 0.33333333, 0.25 ],
[ 2. , 1. , 0.66666667, 0.5 ],
[ 3. , 1.5 , 1. , 0.75 ],
[ 4. , 2. , 1.33333333, 1. ]])