我有一个关于numpy的问题。
我们假设我有一个功能
def calcSomething(A,t):
return t*A
我想传递一个常量numpy数组,例如A=np.array([1.0,2.0])
和t作为等距点,例如t = np.linspace(0.0,1.0,10)
。
现在,当我执行
x = calcSomething(A,t)
我想获得x[0] = [0,0]
,x[1] = [.1,.2]
,...,x[9] = [1.0,2.0]
。有没有一种简单的方法来实现它,或者我是否必须使用for循环并追加它来实现它?
编辑:'calcSomething():只是一个更复杂功能的占位符。
E.g。 y=np.sin(t)
会产生y[i]=np.sin(t[i])
。这就是我想要的通用功能。
提前致谢!
答案 0 :(得分:1)
尽可能使用对整个阵列进行操作的numpy函数和运算符,并为您执行必要的broadcasting
:
In [24]: A = np.array([1.0,2.0]); t = np.linspace(0.0, 1.0, 10)
In [25]: x = t[:,None] * A[None,:]
In [26]: x.shape
Out[26]: (10, 2)
In [27]: x[:3,:]
Out[27]:
array([[0. , 0. ],
[0.11111111, 0.22222222],
[0.22222222, 0.44444444]])
In [28]: np.sin(t)
Out[28]:
array([0. , 0.11088263, 0.22039774, 0.3271947 , 0.42995636,
0.52741539, 0.6183698 , 0.70169788, 0.77637192, 0.84147098])
如果你有一个仅适用于标量输入的函数,你可以使用np.vectorize
从广播数组中提取这些值:
In [30]: def foo(A,t):
...: return t*A
...:
In [31]: f = np.vectorize(foo, otypes=[float])
In [32]: f(A[None,:], t[:,None])
Out[32]:
array([[0. , 0. ],
[0.11111111, 0.22222222],
[0.22222222, 0.44444444],
....
[1. , 2. ]])
vectorize
是一种便利功能;它不承诺速度。将其时间与In[25]
:
In [33]: timeit f(A[None,:], t[:,None])
41.3 µs ± 48.5 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [34]: timeit x = t[:,None] * A[None,:]
5.41 µs ± 8.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
慢了8倍。
或使用标量math.sin
函数:
In [35]: import math
In [36]: g = np.vectorize(math.sin)
...
In [39]: timeit g(t)
39 µs ± 72.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [40]: timeit np.sin(t)
1.4 µs ± 2.72 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
迭代调用math.sin
比np.sin
快,但给定整个数组时np.sin
要快得多。
基本区别在于vectorize
,就像显式循环在解释的Python中迭代一样,并为每个输出元素调用一次函数。 np.sin
和数组*
正在迭代,但是在编译代码中。
在Python和numpy中有各种迭代方法,但它们很少能为你提供超过2倍的加速。
有一些工具可以将计算移动到已编译的代码,例如cython
和numba
。搜索这些标签,了解如何使用它们。
答案 1 :(得分:0)
您可以使用矩阵乘法:
>>> A = np.array([1.0,2.0])
>>> t = np.linspace(0.0,1.0,10)
>>> np.matmul(t.reshape(10, 1), A.reshape(1, 2))
array([[0. , 0. ],
[0.11111111, 0.22222222],
[0.22222222, 0.44444444],
[0.33333333, 0.66666667],
[0.44444444, 0.88888889],
[0.55555556, 1.11111111],
[0.66666667, 1.33333333],
[0.77777778, 1.55555556],
[0.88888889, 1.77777778],
[1. , 2. ]])
答案 2 :(得分:0)
只需使用None
指定新轴:
A[None, :] * t[:, None]