我有一个数组,其中包含负数和积极元素块。一个简单的例子就是数组a
,如:array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])
(a<0).sum()
和(a>0).sum()
给出了负面和正面元素的总数,但我如何按顺序计算这些元素?通过这个我的意思是我想要知道我的数组包含前3个负面元素,6个正面和2个负面。
这听起来像是一个在某个地方被解决过的话题,可能会有重复,但我找不到。
一种方法是在整个数组的循环中使用numpy.roll(a,1)
并计算出现在例如出现的给定符号的元素数量。数组在滚动时的第一个元素,但它对我来说看起来不那么多(或pythonic)也不是非常有效。
答案 0 :(得分:2)
这是一种矢量化方法 -
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
答案 1 :(得分:1)
只需使用
my_array = np.array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])
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]
print(len_list)
你会得到你想要的东西:
Out[1]: [3, 6, 2]
你必须提到你的第一个元素是什么。根据我的代码中的定义,为负面定义。
所以只需执行:
my_array = np.array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])
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]
print(len_list)
答案 2 :(得分:0)
我的(相当简单且可能效率低下)解决方案是:
import numpy as np
arr = np.array([-3, -2, -1, 1, 2, 3, 4, 5, 6, -5, -4])
sgn = np.sign(arr[0])
res = []
cntr = 1 # counting the first one
for i in range(1, len(arr)):
if np.sign(arr[i]) != sgn:
res.append(cntr)
cntr = 0
sgn *= -1
cntr += 1
res.append(cntr)
print res