我是python的新手(甚至编程!),所以我会尽可能清楚地解释我的问题。对你们来说这很容易,但我还没有找到令人满意的结果。
问题在于:
我有一个包含负值和正值的数组,比如说:
x = numpy.array([1, 4, 2, 3, -1, -6, -6, 5, 6, 7, 3, 1, -5, 4, 9, -5, -2, -1, -4])
我想仅总结负值连续,即仅和( - 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])
然而,正如您所料,我只是得到了数组中所有负值的总和。在这种情况下 sum ( - 1,-6,-6,-5,-5,-2,-1,-4) 人们可以与我分享一种美学和有效的方法来解决这个问题吗?我将对此表示感谢。
非常感谢
答案 0 :(得分:7)
您可以使用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]
或者作为更加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]
答案 1 :(得分:1)
这是一个矢量化的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])
您也可以使用np.convolve
获取mask1
,就像这样 -
mask1 = np.convolve(mask.astype(int),np.ones(3),'same')>1
您还可以在每个&#34;岛&#34;中获得负数的计数。对现有代码进行一些调整 -
counts = np.bincount(id[mask1]-1)
示例运行 -
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])
答案 2 :(得分:1)
你可以标记负值....并使用普通python执行此操作
prev = False
for i,v in enumerate(a):
j = i + 1
if j < len(a):
if a[i] < 0 and a[j] < 0:
temp.append(v)
prev = True
elif a[i] < 0 and prev:
temp.append(v)
prev = True
elif a[i] > 0:
prev = False
else:
if prev and v < 0:
temp.append(v)
<强>输出强>
打印(温度)
[ - 1,-6,-6,-5,-2,-1,-4]
使用intertools我会这样做
def sum_conseq_negative(li):
neglistAll = []
for k, g in groupby(li, key=lambda i:i<0):
negList = list(g)
if k and len(negList) > 1:
neglistAll.extend(negList)
return sum(negList), len(negList)
sumOf, numOf = sum_conseq_negative(li)
print("sum of negatives {} number of summed {}".format(sumOf,numOf))
负数之和-25总数7