我有一个numpy数组,其中包含正值和负值.
a = array([1,1,-1,-2,-3,4,5])
Run Code Online (Sandbox Code Playgroud)
我想创建另一个数组,其中包含每个索引处发生符号更改的值(例如,如果当前元素为正,而前一个元素为负,反之亦然).
对于上面的数组,我希望得到以下结果
array([0,0,1,0,0,1,0])
Run Code Online (Sandbox Code Playgroud)
或者,发生符号变化的阵列中的位置列表或者布尔列表而不是0和1的列表是可以的.
jan*_*neb 25
就像是
a = array([1,1,-1,-2,-3,4,5])
asign = np.sign(a)
signchange = ((np.roll(asign, 1) - asign) != 0).astype(int)
print signchange
array([0, 0, 1, 0, 0, 1, 0])
Run Code Online (Sandbox Code Playgroud)
现在,numpy.roll执行循环移位,因此如果最后一个元素的符号与第一个元素的符号不同,则signchange数组中的第一个元素将为1.如果不需要,那么当然可以做一个简单的
signchange[0] = 0
Run Code Online (Sandbox Code Playgroud)
此外,np.sign认为0具有自己的符号,不同于正值或负值.例如,[-1,0,1]的"signchange"数组将为[0,1,1],即使零线仅"交叉"一次.如果这是不希望的,可以插入线
sz = asign == 0
while sz.any():
asign[sz] = np.roll(asign, 1)[sz]
sz = asign == 0
Run Code Online (Sandbox Code Playgroud)
在第一个例子中第2行和第3行之间.
import numpy as np
a = np.array([1,1,-1,-2,-3,4,5])
Run Code Online (Sandbox Code Playgroud)
idx1 = np.where(a[:-1] * a[1:] < 0 )[0] +1
idx1
Out[2]: array([2, 5], dtype=int64)
%timeit np.where(a[:-1] * a[1:] < 0 )[0] + 1
4.31 µs ± 15.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Run Code Online (Sandbox Code Playgroud)
idx2 = np.where(np.sign(a[:-1]) != np.sign(a[1:]))[0] + 1
idx2
Out[4]: array([2, 5], dtype=int64)
%timeit np.where(np.sign(a[:-1]) != np.sign(a[1:]))[0] + 1
3.94 µs ± 20.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Run Code Online (Sandbox Code Playgroud)
idx3 = np.where(np.diff(np.sign(a)) != 0)[0] + 1
idx3
Out[6]: array([2, 5], dtype=int64)
%timeit np.where(np.diff(np.sign(a)) != 0)[0] + 1
9.7 µs ± 36.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
Run Code Online (Sandbox Code Playgroud)
对于大型数组,方法 1 是最好的。