hur*_*ght 6 python arrays numpy
我是python的新手(甚至编程!),所以我会尽可能清楚地解释我的问题.对你们来说这很容易,但我还没有找到满意的结果.
这是问题所在:
我有一个包含负值和正值的数组,比如说:
x = numpy.array([1, 4, 2, 3, -1, -6, -6, 5, 6, 7, 3, 1, -5, 4, 9, -5, -2, -1, -4])
Run Code Online (Sandbox Code Playgroud)
我想总结仅负那些值连续,即,仅总和(-1,-6,-6),总和(-5,-2,-1,-4)等.我已经尝试使用numpy.where,以及基于条件的numpy.split.
例如:
for i in range(len(x)):
if x[i] < 0.:
y[i] = sum(x[i])
Run Code Online (Sandbox Code Playgroud)
但是,正如您所料,我只是得到了数组中所有负值的总和.在这种情况下, sum(-1,-6,-6,-5,-5,-2,-1,-4)可以和我分享一个美学和有效的方法来解决这个问题吗?我将不胜感激.
非常感谢你
您可以使用itertools模块,在这里使用groupby您可以根据这些符号对项目进行分组,然后检查它是否符合key函数中的条件,因此它包含负数,然后产生总和,然后产生它,最后您可以使用chain.from_iterable函数链接结果:
>>> from itertools import groupby,tee,chain
>>> def summ_neg(li):
... for k,g in groupby(li,key=lambda i:i<0) :
... if k:
... yield [sum(g)]
... yield g
...
>>> list(chain.from_iterable(summ_neg(x)))
[1, 4, 2, 3, -13, 5, 6, 7, 3, 1, -5, 4, 9, -12]
Run Code Online (Sandbox Code Playgroud)
或者作为更加pythonic的方式使用列表理解:
list(chain.from_iterable([[sum(g)] if k else list(g) for k,g in groupby(x,key=lambda i:i<0)]))
[1, 4, 2, 3, -13, 5, 6, 7, 3, 1, -5, 4, 9, -12]
Run Code Online (Sandbox Code Playgroud)
这是一个矢量化的 NumPythonic 解决方案 -
# Mask of negative numbers
mask = x<0
# Differentiation between Consecutive mask elements. We would look for
# 1s and -1s to detect rising and falling edges in the mask corresponding
# to the islands of negative numbers.
diffs = np.diff(mask.astype(int))
# Mask with 1s at start of negative islands
start_mask = np.append(True,diffs==1)
# Mask of negative numbers with islands of one isolated negative numbers removed
mask1 = mask & ~(start_mask & np.append(diffs==-1,True))
# ID array for IDing islands of negative numbers
id = (start_mask & mask1).cumsum()
# Finally use bincount to sum elements within their own IDs
out = np.bincount(id[mask1]-1,x[mask1])
Run Code Online (Sandbox Code Playgroud)
您还可以使用np.convolveget mask1,就像这样 -
mask1 = np.convolve(mask.astype(int),np.ones(3),'same')>1
Run Code Online (Sandbox Code Playgroud)
您还可以通过对现有代码进行一些调整来获取每个“岛”中负数的计数 -
counts = np.bincount(id[mask1]-1)
Run Code Online (Sandbox Code Playgroud)
样本运行 -
In [395]: x
Out[395]:
array([ 1, 4, 2, 3, -1, -6, -6, 5, 6, 7, 3, 1, -5, 4, 9, -5, -2,
-1, -4])
In [396]: out
Out[396]: array([-13., -12.])
In [397]: counts
Out[397]: array([3, 4])
Run Code Online (Sandbox Code Playgroud)