Python:将列表中的负值设置为0

时间:2014-07-10 19:35:51

标签: python matplotlib

这看起来很简单,但我在将列表中的负数设置为0时出现问题。这是我的代码:

def subtract_lists(list1, list2):
    list3 = list()
    for i in range(0,len(list1)):
            list3.append(list1[i]-list2[i])
    if i < 0:
            i = 0
    else:
            i = i
    return list3

在使用matplotlib制作堆积条形图时,我正在使用此功能。实质上,list2中的某些值大于list1中的值。对于我所拥有的数据,有负值是没有意义的。基本上任何具有负值的东西都只是绘制成一个实心条。

编辑:只想添加图表的顶部是list3。

编辑2:谢谢大家的帮助。由于简单,我最终使用了这个:

def subtract_lists(list1, list2):
    list3 = list()
    for i in range(0,len(list1)):
            list3.append(max(list1[i]-list2[i], 0))
    return list3

但是我很欣赏所有的解决方案和帮助,我将尝试一些其他的例子来获取学习经验。

3 个答案:

答案 0 :(得分:3)

一种方法是将列表更改为numpy array。然后减法很简单明了,另外你可以使用numpy.clip将负值更改为0. numpy算术运算速度也快得多(如果在这种情况下需要关注,那么不可能)而不是迭代python列表。

import numpy as np

ar1 = np.array(list1)
ar2 = np.array(list2)

ar3 = np.clip(ar1 - ar2, 0, None)

如果您不想使用numpy,那么只需更改此行

即可
list3.append(list1[i] - list2[i])

到这个

list3.append(max(list1[i] - list2[i], 0))

最后,当您在列表上进行迭代以创建新列表时,使用列表解析更加惯用python:

list3 = [max(item1 - item2, 0) for item1, item2 in zip(list1, list2)]

当然,如果列表中等大,那么您必须关注zip实际制作列表副本的事实。因此,如果zip的内存使用量过大,您可以使用izip模块中的itertools。它只是zip的替代品(在这种情况下):

from itertools import izip
list3 = [max(item1 - item2, 0) for item1, item2 in izip(list1, list2)]

答案 1 :(得分:2)

您将i设置为零,而不是list3[i]的内容。

if list3[i] < 0:
    list3[i] = 0

您的else阻止正在设置i=i,但不执行任何操作。对于此检查,您也缺少一级缩进,正确的缩进将如下所示:

def subtract_lists(list1, list2):
    list3 = list()
    for i in range(0,len(list1)):
        list3.append(list1[i]-list2[i])
        if list3[i] < 0:
            list3[i] = 0
return list3

但是,我认为编写这样的函数会更清楚:

def subtract_lists(list1, list2):        
    list3 = []
    for a,b in zip(list1, list2):
        diff = a - b 
        list3.append(diff if diff > 0 else 0)
    return list3

当然有更简洁的解决方案(请查看DrV&#39的回答)。

答案 2 :(得分:1)

 list3 = []
 for i in range(len(list1)):
     list3.append(max(list1[i] - list2[i], 0))

 list3 = [ max(li1-li2, 0) for li1, li2 in zip(list1, list2) ]

zip允许同时迭代两个列表,以便li1li2列表项构成列表的相同位置。 IMO这是最恐怖的方式,在这种情况下,如果我们有两个列表,它可能也是最快的方式。 max负责处理负数,因为零大于li1-li2并被放入list3

jsw给出的解决方案是一个不错的解决方案,但是从列表到ndarray(NumPy数组)的转换是一个缓慢的解决方案。当然,NumPy(不幸的是)不是标准Python发行版的一部分。