用于计算数组中零交叉数的Python代码

Rah*_*ria 11 python arrays performance distribution

我期待计算数组中的值改变极性的次数(编辑:数组中的值交叉为零的次数).

假设我有一个数组:

[80.6  120.8  -115.6  -76.1  131.3  105.1  138.4  -81.3
 -95.3  89.2  -154.1  121.4  -85.1  96.8  68.2]`
Run Code Online (Sandbox Code Playgroud)

我希望伯爵数为8.

一种解决方案是运行循环并检查大于或小于0,并保留先前极性的历史记录.

我们能更快地做到吗?

编辑:我的目的是找到更快的东西,因为我有这些长度在68554308左右的数组,我必须在100多个这样的数组上进行这些计算.

Mik*_*ler 11

这会产生相同的结果:

import numpy as np
my_array = np.array([80.6, 120.8, -115.6, -76.1, 131.3, 105.1, 138.4, -81.3, -95.3,  
                     89.2, -154.1, 121.4, -85.1, 96.8, 68.2])
((my_array[:-1] * my_array[1:]) < 0).sum()
Run Code Online (Sandbox Code Playgroud)

得到:

8
Run Code Online (Sandbox Code Playgroud)

并且似乎是最快的解决方案:

%timeit ((my_array[:-1] * my_array[1:]) < 0).sum()
100000 loops, best of 3: 11.6 µs per loop
Run Code Online (Sandbox Code Playgroud)

与迄今为止最快的相比:

%timeit (np.diff(np.sign(my_array)) != 0).sum()
10000 loops, best of 3: 22.2 µs per loop
Run Code Online (Sandbox Code Playgroud)

也适用于较大的阵列:

big = np.random.randint(-10, 10, size=10000000)
Run Code Online (Sandbox Code Playgroud)

这个:

%timeit ((big[:-1] * big[1:]) < 0).sum()
10 loops, best of 3: 62.1 ms per loop
Run Code Online (Sandbox Code Playgroud)

VS:

%timeit (np.diff(np.sign(big)) != 0).sum()
1 loops, best of 3: 97.6 ms per loop
Run Code Online (Sandbox Code Playgroud)

  • 这不会考虑像“[ 1, 2, 1, 0, -1, -2, -1, 0, 1, 0]”这样的列表。难道我们不想添加:“... + (x == 0)”吗? (2认同)

Mar*_*ius 5

这是一个numpy解决方案.Numpy的方法通常非常快且经过优化,但如果您还没有使用过,numpy那么将列表转换为numpy数组可能会有一些开销:

import numpy as np
my_list = [80.6, 120.8, -115.6, -76.1, 131.3, 105.1, 138.4, -81.3, -95.3,  89.2, -154.1, 121.4, -85.1, 96.8, 68.2]
(np.diff(np.sign(my_list)) != 0).sum()
Out[8]: 8
Run Code Online (Sandbox Code Playgroud)