如何检测numpy数组中元素的符号变化
我有一个包含正数和负数的numpy数组。
a = array([1,1,-1,-2,-3,4,5])
我想创建另一个数组,这个数组在每个索引位置上记录符号变化的值(比如,如果当前元素是正数,而前一个元素是负数,或者反过来)。
对于上面的数组,我希望得到以下结果
array([0,0,1,0,0,1,0])
另外,给出数组中符号变化发生的位置列表,或者用布尔值代替0和1也是可以的。
8 个回答
14
三种方法来确定符号变化的位置
import numpy as np
a = np.array([1,1,-1,-2,-3,4,5])
方法一:把数组中相邻的元素相乘,找出负数
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)
方法二(最快):检查相邻的符号是否不相等
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)
方法三:由ianalis提出。最优雅,但稍微慢一点
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)
编辑:
对于大数组,方法一是最好的选择。
27
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如说,当你在写代码时,可能会发现某个功能没有按预期工作。这时候,很多人会去网上查找解决方案,比如在StackOverflow上提问或者寻找答案。
StackOverflow是一个程序员交流的平台,大家可以在这里分享自己的问题和解决方案。当你在这个平台上提问时,其他程序员会看到你的问题,并尝试给你提供帮助。他们可能会建议你检查代码的某个部分,或者提供一些代码示例来帮助你理解。
总之,StackOverflow是一个很好的资源,可以帮助你解决编程中遇到的各种问题。只要你描述清楚你的问题,通常都会有人愿意帮你。
(numpy.diff(numpy.sign(a)) != 0)*1
37
类似这样的内容
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])
现在,numpy.roll 这个函数会进行循环移动,所以如果最后一个元素的符号和第一个元素不同,那么在符号变化的数组里,第一个元素会是 1。如果你不想要这个效果,可以简单地使用
signchange[0] = 0
另外,np.sign 这个函数认为 0 有它自己的符号,这个符号和正数或负数都不一样。比如,对于数组 [-1,0,1],符号变化的数组会是 [0,1,1],尽管零只“跨越”了一次。如果你不想要这个效果,可以在第一个例子的第 2 行和第 3 行之间插入以下代码
sz = asign == 0
while sz.any():
asign[sz] = np.roll(asign, 1)[sz]
sz = asign == 0
。