这个问题从寻找提供的答案茎关于计数的数量问题过零点 提供了几个解决问题的答案,但NumPy appproach在时间上摧毁了其他人。

当我比较四个答案时,我注意到NumPy解决方案为大序列提供了不同的结果。 有问题的四个答案是循环和简单生成器更好的生成器表达式NumPy解决方案

问题:为什么NumPy解决方案提供的结果与其他三种解决方案不同? (哪个是正确的?)

以下是计算过零次数的结果:

Blazing fast NumPy solution
total time: 0.303605794907 sec
Zero Crossings Small: 8
Zero Crossings Med: 54464
Zero Crossings Big: 5449071

Loop solution
total time: 15.6818780899 sec
Zero Crossings Small: 8
Zero Crossings Med: 44960
Zero Crossings Big: 4496847

Simple generator expression solution
total time: 16.3374049664 sec
Zero Crossings Small: 8
Zero Crossings Med: 44960
Zero Crossings Big: 4496847

Modified generator expression solution
total time: 13.6596589088 sec
Zero Crossings Small: 8
Zero Crossings Med: 44960
Zero Crossings Big: 4496847

用于获得结果的代码:

import time
import numpy as np

def zero_crossings_loop(sequence):
    s = 0
    for ind, _ in enumerate(sequence):
        if ind+1 < len(sequence):
            if sequence[ind]*sequence[ind+1] < 0:
                s += 1
    return s

def print_three_results(r1, r2, r3):
    print 'Zero Crossings Small:', r1
    print 'Zero Crossings Med:', r2
    print 'Zero Crossings Big:', r3
    print '\n'

small = [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]
med = np.random.randint(-10, 10, size=100000)
big = np.random.randint(-10, 10, size=10000000)

print 'Blazing fast NumPy solution'
tic = time.time()
z1 = (np.diff(np.sign(small)) != 0).sum()
z2 = (np.diff(np.sign(med)) != 0).sum()
z3 = (np.diff(np.sign(big)) != 0).sum()
print 'total time: {0} sec'.format(time.time()-tic)
print_three_results(z1, z2, z3)

print 'Loop solution'
tic = time.time()
z1 = zero_crossings_loop(small)
z2 = zero_crossings_loop(med)
z3 = zero_crossings_loop(big)
print 'total time: {0} sec'.format(time.time()-tic)
print_three_results(z1, z2, z3)

print 'Simple generator expression solution'
tic = time.time()
z1 = sum(1 for i, _ in enumerate(small) if (i+1 < len(small)) if small[i]*small[i+1] < 0)
z2 = sum(1 for i, _ in enumerate(med) if (i+1 < len(med)) if med[i]*med[i+1] < 0)
z3 = sum(1 for i, _ in enumerate(big) if (i+1 < len(big)) if big[i]*big[i+1] < 0)
print 'total time: {0} sec'.format(time.time()-tic)
print_three_results(z1, z2, z3)

print 'Modified generator expression solution'
tic = time.time()
z1 = sum(1 for i in xrange(1, len(small)) if small[i-1]*small[i] < 0)
z2 = sum(1 for i in xrange(1, len(med)) if med[i-1]*med[i] < 0)
z3 = sum(1 for i in xrange(1, len(big)) if big[i-1]*big[i] < 0)
print 'total time: {0} sec'.format(time.time()-tic)
print_three_results(z1, z2, z3)

===============>>#1 票数:5 已采纳

您的解决方案的零处理方式不同。 numpy.diff解决方案仍将返回从-1到0或1到0的差异,将其计为零交叉,而迭代解决方案则不会,因为它们使用小于零的乘积作为其标准。 相反,测试<= 0 ,数字将是等价的。

===============>>#2 票数:4

我得到与循环相同的结果:

((array[:-1] * array[1:]) < 0).sum()

这个:

small = 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])
med = np.random.randint(-10, 10, size=100000)
big = np.random.randint(-10, 10, size=10000000)

for name, array in [('small', small), ('med', med), ('big', big)]:
    print('loop ', name, zero_crossings_loop(array))
    print('Numpy', name, ((array[:-1] * array[1:]) < 0).sum())

打印:

loop  small 8
Numpy small 8
loop  med 44901
Numpy med 44901
loop  big 4496911
Numpy big 4496911

UDPATE

此版本避免了零问题:

def numpy_zero_crossings2(array):
    nonzero_array = array[np.nonzero(array)]
    return ((nonzero_array[:-1] * nonzero_array[1:]) < 0).sum()

它给出了与@djsutton的答案相同的结果:

>>> numpy_zero_crossings2(big) == numpy_zero_crossings(big)     
True

看起来有点快:

%timeit numpy_zero_crossings2(big)
1 loops, best of 3: 194 ms per loop

VS:

%timeit numpy_zero_crossings(big)
1 loops, best of 3: 227 ms per loop

===============>>#3 票数:3

当数据元素等于零时,迭代和numpy解决方案在计算交叉时表现不佳。 对于数据[1,0,-1],迭代解决方案给出了0个交叉点,而numpy解决方案给出了2个交叉点,这两个交叉点似乎都不正确。

一种解决方案是丢弃等于零的数据元素。 在NumPy你可能会尝试类似的东西

def numpy_zero_crossings(data):
    return (np.diff(np.sign(data)[np.nonzero(data)]) != 0).sum()

但是,这引入了另一个遍历数组的迭代,因此它会增加另一个O(n)的运行时间

  ask by Scott translate from so

未解决问题?本站智能推荐:

3回复

如何计算熊猫系列中前一个零点的距离?

我有以下熊猫系列(表示为列表): 我想定义一个返回到最后零点的距离的新系列。 这意味着我希望得到以下输出: 如何以最有效的方式在熊猫中做到这一点?
2回复

将零点连接为零点

我有一个这样的数据集,其中我有一组xs值,并用ys值绘制了相应的线形图。 如果默认情况下注意到,则图将连接点并绘制线。 但是,我想在0点画一条线以找到缺失的点。 我该怎么做呢 ? 我应该操纵数据以零填充缺失值(numpy,也许),还是有办法绘制此matplotlib.plot ?
2回复

如何找到滞后过零点?

在numpy中,我想检测信号从(先前已经)低于某个阈值的点到高于某个其他阈值。 这适用于诸如去抖动或在存在噪声等情况下的准确过零点之类的事情。 像这样: 我想要一种方法来做到这一点,而不是明确地循环数组:但我想不出任何方式,因为每个状态值取决于以前的状态。 有可能没有循环吗?
4回复

创建多维零点Python

我需要制作一个零的多维数组。 对于两个(D = 2)或三个(D = 3)尺寸,这很容易,我会使用: 要么 如何为更高的D,制作长度为n的数组?
3回复

python中的4维零点数组

我想在python中创建一个4维的零数组。 我知道如何为方阵做这个,但我希望列表有不同的长度。 现在我用这个: 这给了他们所有的长度200,但我想有200,20,100,20长度,因为现在我的阵列中有很多零,我不使用
3回复

用Python找到矩阵特征多项式的零点

给定N×N对称矩阵C和N×N对角矩阵I ,求出方程det(λI-C)=0 。 换句话说,要找到C的(广义)特征值。 我知道如何使用内置函数在MATLAB中解决这个问题: 第一种方式: 第二种方式: 但是,我需要使用Python。 在NumPy和SymPy中有类似的
2回复

在numpy中找到最小跳跃过零点

对于数据分析任务,我想在numpy数组中找到零交叉,来自卷积,首先是类似sobel的内核,然后是墨西哥帽内核。 过零允许我检测数据中的边缘。 不幸的是,数据有些嘈杂,我只想找到最小跳跃大小的过零点,在下面的示例中为20 : 应该导致 要么 其中3是-1的索引,就在
1回复

如何在堆积条形图显示中抑制零点

我有一个样本堆积条形码如下所示。 如何在图表中抑制“0”值 无论我在哪里,我都不想显示这些值。 有什么方法可以压制零 我在显示数据时有下面的代码 我试过以下方法 有什么方法可以实现 以及如何使y轴按照数据显示(如下图所示,我在Y轴上最多有6个。我使用np.
1回复

QR分解与Householder变换-零点的引入尚不清楚

我目前正在尝试对矩形矩阵实施基于Householder的QR分解,如http://eprints.ma.man.ac.uk/1192/1/qrupdating_12nov08.pdf (第3、4、5页)所述。 显然我弄错了一些伪代码,因为(1)我的结果不同于numpy.qr.linalg(
3回复

是否有pandas / numpy函数在后续零点之间传播整数?

我试图转向,例如,以下字符串: 成: 因此,每个整数被划分为偶数部分,并在它自己的位置和以下零之间进行分割。 我主要是一个R用户,并在R完成了这个: 我很难在Python中找到类似的简单流程,是否存在?