Python 将列表转换为包含更多或更少项的列表,保持列表和项之间的相对差异

Python 将列表转换为包含更多或更少项的列表,保持列表和项之间的相对差异,python,numpy,Python,Numpy,我有一张5项的清单 [6,4,2,4,6] 如果我需要10个项目长的列表,具有相同的总和和相对分布,它看起来应该是这样的 [3,3,2,2,1,1,2,2,3,3] 这很简单,因为由于项目数量增加了一倍,我只需将上一个列表中的每个项目一分为二 我想找出一种方法,让第一张单子的长度不受项目数的限制。也许3,7,12999 很明显,要做到完美通常是不可能的,因为在这个简单的例子中,我试图找到一个提供最佳拟合的解决方案。IIUC,使用np。重复: 输出: array([3., 3., 2., 2.

我有一张5项的清单

[6,4,2,4,6]
如果我需要10个项目长的列表,具有相同的总和和相对分布,它看起来应该是这样的

[3,3,2,2,1,1,2,2,3,3]
这很简单,因为由于项目数量增加了一倍,我只需将上一个列表中的每个项目一分为二

我想找出一种方法,让第一张单子的长度不受项目数的限制。也许3,7,12999

很明显,要做到完美通常是不可能的,因为在这个简单的例子中,我试图找到一个提供最佳拟合的解决方案。

IIUC,使用np。重复:

输出:

array([3., 3., 2., 2., 1., 1., 2., 2., 3., 3.])

有很多方法可以满足您的规范,具体取决于您希望保留的发行版属性。一种方法是将其视为插值问题,并尝试将分布的分数保留到给定的相对x坐标。我们可以取这些值的累积和,在所需的目标点处插值,然后将结果差值:

def resampler(orig, N):
    x = np.arange(len(orig) + 1)
    y = np.insert(orig.cumsum(), 0, 0)
    target = np.linspace(0, len(orig), N+1)
    integ = np.interp(target, xp=x, fp=y)
    result = np.diff(integ)
    return result
给我

In [137]: x = np.array([6,4,2,4,6])

In [138]: resampler(x, 5)
Out[138]: array([ 6.,  4.,  2.,  4.,  6.])

In [139]: resampler(x, 10)
Out[139]: array([ 3.,  3.,  2.,  2.,  1.,  1.,  2.,  2.,  3.,  3.])

In [140]: resampler(x, 3)
Out[140]: array([ 8.66666667,  4.66666667,  8.66666667])

In [141]: resampler(x, 3).sum()
Out[141]: 22.0

In [142]: resampler(x, 20)
Out[142]: 
array([ 1.5,  1.5,  1.5,  1.5,  1. ,  1. ,  1. ,  1. ,  0.5,  0.5,  0.5,
        0.5,  1. ,  1. ,  1. ,  1. ,  1.5,  1.5,  1.5,  1.5])

In [143]: resampler(x, 13)
Out[143]: 
array([ 2.30769231,  2.30769231,  2.        ,  1.53846154,  1.53846154,
        0.92307692,  0.76923077,  0.92307692,  1.53846154,  1.53846154,
        2.        ,  2.30769231,  2.30769231])

In [144]: resampler(x, 13).sum()
Out[144]: 22.0

1是否限制为整数值?2你更关心分布匹配还是总和匹配?我知道我是模棱两可的-1没有非整数是好的,2总和必须匹配,分布尽可能接近每一个接近,非常令人印象深刻。不幸的是,我模棱两可。列表必须具有所需的项目数。但是,项目不需要是整数。whistle+1很好!这正是我所希望的,而你甚至帮我想出了如何要求它。
In [137]: x = np.array([6,4,2,4,6])

In [138]: resampler(x, 5)
Out[138]: array([ 6.,  4.,  2.,  4.,  6.])

In [139]: resampler(x, 10)
Out[139]: array([ 3.,  3.,  2.,  2.,  1.,  1.,  2.,  2.,  3.,  3.])

In [140]: resampler(x, 3)
Out[140]: array([ 8.66666667,  4.66666667,  8.66666667])

In [141]: resampler(x, 3).sum()
Out[141]: 22.0

In [142]: resampler(x, 20)
Out[142]: 
array([ 1.5,  1.5,  1.5,  1.5,  1. ,  1. ,  1. ,  1. ,  0.5,  0.5,  0.5,
        0.5,  1. ,  1. ,  1. ,  1. ,  1.5,  1.5,  1.5,  1.5])

In [143]: resampler(x, 13)
Out[143]: 
array([ 2.30769231,  2.30769231,  2.        ,  1.53846154,  1.53846154,
        0.92307692,  0.76923077,  0.92307692,  1.53846154,  1.53846154,
        2.        ,  2.30769231,  2.30769231])

In [144]: resampler(x, 13).sum()
Out[144]: 22.0