看起来显式计算向量数组的叉积比使用 快得多np.cross。我尝试过向量优先和向量最后,它似乎没有什么区别,尽管这是在类似问题的答案中提出的。是我用错了,还是速度慢了?
在笔记本电脑上,显式计算每个叉积大约需要 60 纳秒。这大概是最快的速度吗?在这种情况下,似乎还没有任何理由去使用 Cython 或 PyPy 或编写特别内容ufunc。
我还看到了对 einsum 使用的引用,但我不太明白如何使用它,并且怀疑它不是更快。
a = np.random.random(size=300000).reshape(100000,3) # vector last
b = np.random.random(size=300000).reshape(100000,3)
c, d = a.swapaxes(0, 1), b.swapaxes(0, 1) # vector first
def npcross_vlast(): return np.cross(a, b)
def npcross_vfirst(): return np.cross(c, d, axisa=0, axisb=0)
def npcross_vfirst_axisc(): return np.cross(c, d, axisa=0, axisb=0, axisc=0)
def explicitcross_vlast():
e = np.zeros_like(a)
e[:,0] = a[:,1]*b[:,2] - a[:,2]*b[:,1]
e[:,1] = a[:,2]*b[:,0] - a[:,0]*b[:,2]
e[:,2] = a[:,0]*b[:,1] - a[:,1]*b[:,0]
return e
def …Run Code Online (Sandbox Code Playgroud) 我有一个平面数组b:
a = numpy.array([0, 1, 1, 2, 3, 1, 2])
Run Code Online (Sandbox Code Playgroud)
以及c标记每个“块”开始的索引数组:
b = numpy.array([0, 4])
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用归约找到每个“块”中的最大值:
m = numpy.maximum.reduceat(a,b)
>>> array([2, 3], dtype=int32)
Run Code Online (Sandbox Code Playgroud)
但是...有没有一种方法可以通过向量化操作(无列表、循环)找到<edit>块内最大值的索引</edit>(例如)?numpy.argmax
我偶尔会where在 numpy 的 ufunc 中使用该子句。例如,以下内容:
import numpy as np
a = np.linspace(-1, 1, 10)
np.sqrt(a, where=a>0) * (a>0)
Run Code Online (Sandbox Code Playgroud)
在 Numpy 1.12 及更早版本中,这曾经在可能的情况下给我平方根值,否则为零。
不过,最近我升级到 numpy 1.13。上面的代码现在给了我以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Automatic allocation was requested for an iterator operand, and it was flagged as readable, but buffering without delayed allocation was enabled
Run Code Online (Sandbox Code Playgroud)
我认为这正是该where条款应该使用的方式,但也许我错了。所以我有两个问题:第一,这段代码有什么问题;其次,实现我的目标的推荐方法是什么?
7 年多以来一直存在一些相关问题,但我再次提出这个问题,因为我看不到提供“numpy”方式迭代方法。
任务如下:如果我有一个 numpy 数组“arr”并且有一个自定义函数“fn”,我如何在“arr”上迭代应用“fn”?'fn' 不能由 ufunc 工具构造。
下面是我想出的玩具代码:
import numpy as np
r_list = np.arange(1,6,dtype=np.float32)
# r_list = [1. 2. 3. 4. 5.]
r_list_extended = np.append([0.],r_list)
R_list_extended = np.zeros_like(r_list_extended)
print(r_list)
gamma = 0.99
pv_mc = lambda a, x: x+ a*gamma
# no cumsum, accumulate available
for i in range(len(r_list_extended)):
if i ==0: continue
else: R_list_extended[i] = pv_mc(R_list_extended[i-1],r_list_extended[i])
R_list = R_list_extended[1:]
print(R_list)
# R_list == [ 1. 2.99 5.9601 9.900499 14.80149401]
Run Code Online (Sandbox Code Playgroud)
r_list 是每次 r 的数组。R_list是折扣r的累积和。假设 r_list 和 R_list …
在函数 apply_ufunc的xarray 文档中,它说:
dask: ‘forbidden’, ‘allowed’ or ‘parallelized’, optional
How to handle applying to objects containing lazy data in the form of dask arrays:
‘forbidden’ (default): raise an error if a dask array is encountered.
‘allowed’: pass dask arrays directly on to func.
‘parallelized’: automatically parallelize func if any of the inputs are a dask array.
If used, the output_dtypes argument must also be provided.
Multiple output arguments are not yet supported.
Run Code Online (Sandbox Code Playgroud)
在Parallel Computing的文档页面中,有一个注释:
对于大多数已经由 dask …
我想知道是否有可能对两个形状相同的结构化 numpy 数组执行元素求和(或其他操作)。
arr1 = np.array([[1,2,3],[2,3,4]], dtype=[("x", "f8"),("y", "f8")])
arr2 = np.array([[5,4,3],[9,6,4]], dtype=[("x", "f8"),("y", "f8")])
arr3 = np.sum(arr1, arr2)
Run Code Online (Sandbox Code Playgroud)
说“ufunc 'add' 不包含签名匹配类型 dtype([('x', '
如果这是不可能的,那么理解为什么在 numpy 中实现它是不可能或不切实际的将会很好。
ndarray大多数时候使用 numpy s 我们不需要担心我们漂亮的小脑袋关于内存布局,因为结果不依赖于它。
除非他们这样做。例如,考虑这种设置 3x2 矩阵对角线的稍微过度设计的方法
>>> a = np.zeros((3,2))
>>> a.reshape(2,3)[:,0] = 1
>>> a
array([[1., 0.],
[0., 1.],
[0., 0.]])
Run Code Online (Sandbox Code Playgroud)
只要我们控制好内存布局a就可以了。但是,如果我们不这样做,那就是一个错误,更糟糕的是,这是一个令人讨厌的无声错误:
>>> a = np.zeros((3,2),order='F')
>>> a.reshape(2,3)[:,0] = 1
>>> a
array([[0., 0.],
[0., 0.],
[0., 0.]])
Run Code Online (Sandbox Code Playgroud)
这足以表明内存布局不仅仅是一个实现细节。
为了了解数组布局,人们可能合理地要求的第一件事是新数组是什么样的?这些工厂empty,ones,zeros,identity每默认等回报C-连续布局。
但是,此规则并未扩展到 numpy 分配的每个新数组。例如:
>>> a = np.arange(8).reshape(2,2,2).transpose(1,0,2)
>>> aa = a*a
Run Code Online (Sandbox Code Playgroud)
乘积aa是 ufunc 分配的新数组np.multiply。它是 C 连续的吗?不:
>>> aa.strides
(16, 32, 8)
Run Code Online (Sandbox Code Playgroud)
我的猜测是,这是优化的结果,该优化认识到可以在平面线性阵列上完成此操作,这将解释为什么输出具有与输入相同的内存布局。
事实上,这甚至很有用,不像下面的废话函数。它显示了一个方便的习惯用法来实现轴参数,同时仍然保持索引简单。 …
我正在尝试编写一个函数来检测所有上升沿 - 向量中值超过特定阈值的索引。这里描述了类似的内容:Python上升/下降沿示波器式触发器,但我想添加滞后,这样触发器就不会触发,除非该值低于另一个限制。
我想出了以下代码:
import numpy as np
arr = np.linspace(-10, 10, 60)
sample_values = np.sin(arr) + 0.6 * np.sin(arr*3)
above_trigger = sample_values > 0.6
below_deadband = sample_values < 0.0
combined = 1 * above_trigger - 1 * below_deadband
Run Code Online (Sandbox Code Playgroud)
现在,在combined数组中1,原始值高于上限,-1原始值低于下限,0原始值介于两者之间:
>>> combined
array([ 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 0, 0,
1, 1, 1, 0, -1, -1, -1, -1, -1, -1, …Run Code Online (Sandbox Code Playgroud) 我对 numpy 有点陌生,并且正在努力解决这个问题。我有两个二维 numpy 数组:
array1 = [a1, a2, ..., an]
array2 = [b1, b2, ..., am]
Run Code Online (Sandbox Code Playgroud)
a1, a2, b1, 和b2都是一维数组,其中正好有 100 个浮点数。然而,array1与array2具有不同的长度。所以array1和分别array2具有形状(n, 100)和(m, 100),其中n和m是任意长度。
我想在它们之间执行某种修改后的点积,以便我可以输出以下矩阵:
array([[ a1+b1, a1+b2, a1+b3, ...],
[ a2+b1, a2+b2, a2+b3, ...],
[ a3+b1, a3+b2, a3+b3, ...],
[...]])
Run Code Online (Sandbox Code Playgroud)
我明白这np.dot(array1, array2.T)让我非常接近。它只是给我a1•b1而不是a1+b1在所需的输出数组中。
使用 numpy 获取所需数组的最有效的计算方法是什么?提前致谢!
我做了一些计算和测量的性能ufuncs喜欢np.cumsum在不同的轴,以使代码更高性能.
In [51]: arr = np.arange(int(1E6)).reshape(int(1E3), -1)
In [52]: %timeit arr.cumsum(axis=1)
2.27 ms ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [53]: %timeit arr.cumsum(axis=0)
4.16 ms ± 10.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)
cumsum超过轴1的速度几乎比cumsum轴0 快2倍.为什么它会如此以及幕后发生了什么?能够清楚地了解其背后的原因是很好的.谢谢!
更新:经过一些研究后,我意识到如果有人正在构建一个总是只对某个轴求和的应用程序,那么应该按照适当的顺序初始化数组:即轴的C顺序 = 1和或Fortran-order for axis = 0 sums,以节省CPU时间.
另外:关于连续和非连续数组之间差异的这个优秀答案帮助了很多!
numpy ×10
numpy-ufunc ×10
python ×7
argmax ×1
arrays ×1
dask ×1
iterator ×1
performance ×1
python-2.7 ×1
python-3.x ×1
reduction ×1
tensorflow ×1