NumPy数组中负数和正数的孤岛计数 [英] Count of islands of negative and positive numbers in a NumPy array

查看:158
本文介绍了NumPy数组中负数和正数的孤岛计数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含负片和正片的数组.一个非常简化的示例将是一个数组a,如下所示:array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])

I have an array containing chunks of negative and chunks of positive elements. A much simplified example of it would be an array a looking like: array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])

(a<0).sum()(a>0).sum()给出了负数和正数元素的总数,但是如何按顺序对它们进行计数?通过这种方式,我想知道我的数组包含前3个负数元素,6个正数和2个负数.

(a<0).sum() and (a>0).sum() give me the total number of negative and positive elements but how do I count these in order? By this I mean I want to know that my array contains first 3 negative elements, 6 positive and 2 negative.

这听起来像是一个话题,已经在某个地方解决了,那里可能有重复的话题,但我找不到.

This sounds like a topic that have been addressed somewhere, and there may be a duplicate out there, but I can't find one.

一种方法是在整个数组中循环使用numpy.roll(a,1)并计算出现在例如滚动时数组的第一个元素,但是对我来说,它看起来并没有太多的numpyic(或pythonic),也没有很高的效率.

A method is to use numpy.roll(a,1) in a loop over the whole array and count the number of elements of a given sign appearing in e.g. the first element of the array as it rolls, but it doesn't look much numpyic (or pythonic) nor very efficient to me.

推荐答案

这里是一种矢量化方法-

Here's one vectorized approach -

def pos_neg_counts(a):
    mask = a>0
    idx = np.flatnonzero(mask[1:] != mask[:-1])
    count = np.concatenate(( [idx[0]+1], idx[1:] - idx[:-1], [a.size-1-idx[-1]] ))
    if a[0]<0:
        return count[1::2], count[::2] # pos, neg counts
    else:
        return count[::2], count[1::2] # pos, neg counts

样品运行-

In [155]: a
Out[155]: array([-3, -2, -1,  1,  2,  3,  4,  5,  6, -5, -4])

In [156]: pos_neg_counts(a)
Out[156]: (array([6]), array([3, 2]))

In [157]: a[0] = 3

In [158]: a
Out[158]: array([ 3, -2, -1,  1,  2,  3,  4,  5,  6, -5, -4])

In [159]: pos_neg_counts(a)
Out[159]: (array([1, 6]), array([2, 2]))

In [160]: a[-1] = 7

In [161]: a
Out[161]: array([ 3, -2, -1,  1,  2,  3,  4,  5,  6, -5,  7])

In [162]: pos_neg_counts(a)
Out[162]: (array([1, 6, 1]), array([2, 1]))

运行时测试

其他方法-

# @Franz's soln        
def split_app(my_array):
    negative_index = my_array<0
    splits = np.split(negative_index, np.where(np.diff(negative_index))[0]+1)
    len_list = [len(i) for i in splits]
    return len_list

更大数据集上的时间-

In [20]: # Setup input array
    ...: reps = np.random.randint(3,10,(100000))
    ...: signs = np.ones(len(reps),dtype=int)
    ...: signs[::2] = -1
    ...: a = np.repeat(signs, reps)*np.random.randint(1,9,reps.sum())
    ...: 

In [21]: %timeit split_app(a)
10 loops, best of 3: 90.4 ms per loop

In [22]: %timeit pos_neg_counts(a)
100 loops, best of 3: 2.21 ms per loop

这篇关于NumPy数组中负数和正数的孤岛计数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆