修改了列表中累积的数字总和

时间:2015-08-10 09:02:12

标签: python list numpy numbers cumulative-sum

我想根据列表中的累积数字来创建新列表。输入是理想的 - 可以分裂为子集,每个子​​集的总和相等。子集的长度不相等。输入子集数。

每个输出子集代表增量整数[0,1,2,3,...],它代替原始输入。整数的数量是子集的数量。

示例:

number of subsets = 2   

input = [1, 4, 5]
#cumsum = [1, 5, 10]
subsets = [1,5], [10]
output-subsets = [0,0], [1]
output = [0, 0, 1]

例1:

number of subsets = 4

input = [1, 2, 3, 4, 2, 5, 1, 6]
#cumsum = [1, 3, 6, 10, 12, 17, 18, 24]
subsets = [1,3,6], [10, 12],[17, 18], [24]
output-subsets = [0, 0, 0], [1, 1], [2, 2], [3]
output = [0, 0, 0, 1, 1, 2, 2, 3]

number of subsets = 2

input = [1, 2, 3, 4, 2, 5, 1, 6]
#cumsum = [1, 3, 6, 10, 12, 17, 18, 24]
subsets = [1, 3, 6, 10, 12],[17, 18, 24]
output-subsets = [0, 0, 0, 0, 0], [1, 1, 1]
output = [0, 0, 0, 0, 0, 1, 1, 1]

我尝试修改SO question

def changelist(lis, t):
    total = 0

    s = sum(lis)
    subset = s/t

    for x in lis:
        total += x
        i= 1
        if(total <= subset):
            i = 0
        yield i


#changelist([input array], number of subset)    
print list(changelist([1, 2, 3, 4, 2, 5, 1, 6], 4))     

但只有第一个子集是正确的:

output = [0, 0, 0, 1, 1, 1, 1, 1]

我认为numpy.array_split存在问题strange behaviour of numpy array_split

我真的很喜欢任何解释或帮助。

2 个答案:

答案 0 :(得分:2)

这可以解决您的问题:

def changelist (l, t):
  subset = sum(l) / t
  current, total = 0, 0
  for x in l:
    total += x
    if total > subset:
      current, total = current + 1, x
    yield current

示例:

>>> list(changelist([1, 4, 5], 2))
[0, 0, 1]
>>> list(changelist([1, 2, 3, 4, 2, 5, 1, 6], 4))
[0, 0, 0, 1, 1, 2, 2, 3]
>>> list(changelist([1, 2, 3, 4, 2, 5, 1, 6], 2))
[0, 0, 0, 0, 0, 1, 1, 1]

它是如何运作的?

  • current存储当前子集的“id”,total当前子集的总和。
  • 对于初始列表x中的每个元素l,如果此total大于每个子集的预期总和,则将其值添加到当前total (我的代码中为subset),然后您知道自己位于下一个子集(current = current + 1)中,并将当前子集的总数“重置”为actuel元素(total = x

答案 1 :(得分:1)

您可以在将NumPy转换为矢量化解决方案的数组后使用input,假设N为子集数量,如此处所列 -

def modified_cumsum(input,N):
    A = np.asarray(input).cumsum()
    return np.append(False,np.in1d(A,(1+np.arange(N))*A[-1]/N))[:-1].cumsum()

样品运行 -

In [31]: N = 2  #number of subsets
    ...: input = [1, 4, 5]
    ...: 

In [32]: modified_cumsum(input,N)
Out[32]: array([0, 0, 1])

In [33]: N = 4  #number of subsets
    ...: input = [1, 2, 3, 4, 2, 5, 1, 6]
    ...: 

In [34]: modified_cumsum(input,N)
Out[34]: array([0, 0, 0, 1, 1, 2, 2, 3])

In [35]: N = 2  #number of subsets
    ...: input = [1, 2, 3, 4, 2, 5, 1, 6]
    ...: 

In [36]: modified_cumsum(input,N)
Out[36]: array([0, 0, 0, 0, 0, 1, 1, 1])