查找所有可能的分配组合

时间:2019-08-23 18:22:09

标签: python pandas

我有一组状态,需要找到状态之间所有可能的分配组合。组中的状态数可以是三个,四个或五个。例如,一组州包括NY,NJ和CT。一个组的总分配为100%。每个州的最低分配为10%。增量分配为10%。对于这三人一组,我需要生成以下内容:

NY     NJ     CT
10%    10%    80%
10%    20%    70%
10%    30%    60%
10%    40%    50%
10%    50%    40%
10%    60%    30%
10%    70%    20%
10%    80%    10%
20%    10%    70%
20%    20%    60%
20%    30%    50%
20%    40%    40%
20%    50%    30%
20%    60%    20%
20%    70%    10%
30%    10%    60%
30%    20%    50%
30%    30%    40%
30%    40%    30%
30%    50%    20%
30%    60%    10%
40%    10%    50%
40%    20%    40%
40%    30%    30%
40%    40%    20%
40%    50%    10%
50%    10%    40%
50%    20%    30%
50%    30%    20%
50%    40%    10%
60%    10%    30%
60%    20%    20%
60%    10%    10% 
70%    10%    20%
70%    20%    10%
80%    10%    10%

一个组中的状态数可以是三个,四个或五个。增量分配也可以是5%或20%。每个州的最低分配固定为10%。最小分配百分比并不总是与增量百分比相同。我尝试在线研究,却没有发现任何切实的东西。您能提出一些有关如何解决此问题的想法吗?谢谢。

2 个答案:

答案 0 :(得分:1)

这里是黑客,但会产生结果。

from itertools import combinations_with_replacement
from collections import Counter
from pprint import pprint

# global constant
INCR = 10

def sums(n,r):
    results = []
    c = {k: v for k, v in zip(range(r), [0]* r)}
    for tpl in combinations_with_replacement(range(r), n):
        d = c.copy()
        d.update(Counter(tpl))

        tpl = tuple(map(lambda x: x*INCR, d.values()))

        if all(tpl):
            results.append(tpl)
    return results


number_of_states = 3

data = sums(100//INCR,number_of_states)

pprint(data)

输出:

[(80, 10, 10),
 (70, 20, 10),
 (70, 10, 20),
 (60, 30, 10),
 (60, 20, 20),
 (60, 10, 30),
 (50, 40, 10),
 (50, 30, 20),
 (50, 20, 30),
 (50, 10, 40),
 (40, 50, 10),
 (40, 40, 20),
 (40, 30, 30),
 (40, 20, 40),
 (40, 10, 50),
 (30, 60, 10),
 (30, 50, 20),
 (30, 40, 30),
 (30, 30, 40),
 (30, 20, 50),
 (30, 10, 60),
 (20, 70, 10),
 (20, 60, 20),
 (20, 50, 30),
 (20, 40, 40),
 (20, 30, 50),
 (20, 20, 60),
 (20, 10, 70),
 (10, 80, 10),
 (10, 70, 20),
 (10, 60, 30),
 (10, 50, 40),
 (10, 40, 50),
 (10, 30, 60),
 (10, 20, 70),
 (10, 10, 80)]

编辑:要获得20%或%5的范围,请将INCR更改为所需的百分比。

答案 1 :(得分:0)

如果这是您拥有的数据,则可以通过添加新列来进行检查

states = df.columns.to_list()#list_of_states_having distribution
df['sum'] = pd.Series(data = np.zeros((df.shape[0],1)))
for state in states:
  df['sum'] += df[state].apply(lambda x:np.int(x.split[:-1]))

df[df['sum']==100]