Pythonic方式获得3d矩阵的所有独特因子组合

时间:2017-03-04 17:09:52

标签: python numpy math combinations itertools

所以我有两个列表,一个看起来像:

drivers = ['bob','Lenny','frank','sunny']

另一个看起来像:

cities = ['Austin','San Antonio','Houston']

这可以通过如下表格轻松表示:

            |  bob  | lenny | frank | sunny
Austin      |  $45  |  $15  |  $77  |  $33
San Antonio |  $12  |  $23  |  $10  |  $18
Houston     |  $44  |  $99  |  $78  |  $12

所以我想计算所有VALID组合,这意味着我可以将赛车留在赛程表之外,但我不能在两个城市同时放置一个赛车,而且我不能离开没有车手的城市。

有什么想法吗?

2 个答案:

答案 0 :(得分:4)

如果您可以假设 cities中的所有城市都是唯一的,您可以简单地生成所有长度len(cities)的{​​{3}}和(可选)将它们与以下城市联系起来:

def valid_combinations(cities,drivers):
    return itertools.permutations(drivers,len(cities))

或者如果您想将它们与城市一起压缩:

def valid_combinations(cities,drivers):
    for perm in itertools.permutations(drivers,len(cities)):
        yield zip(cities,perm)

对于我们生成的最后一个:

>>> list(map(tuple,valid_combinations(cities,drivers)))
[(('Austin', 'bob'), ('San Antonio', 'Lenny'), ('Houston', 'frank')),
(('Austin', 'bob'), ('San Antonio', 'Lenny'), ('Houston', 'sunny')),
(('Austin', 'bob'), ('San Antonio', 'frank'), ('Houston', 'Lenny')),
(('Austin', 'bob'), ('San Antonio', 'frank'), ('Houston', 'sunny')),
(('Austin', 'bob'), ('San Antonio', 'sunny'), ('Houston', 'Lenny')),
(('Austin', 'bob'), ('San Antonio', 'sunny'), ('Houston', 'frank')),
(('Austin', 'Lenny'), ('San Antonio', 'bob'), ('Houston', 'frank')),
(('Austin', 'Lenny'), ('San Antonio', 'bob'), ('Houston', 'sunny')),
(('Austin', 'Lenny'), ('San Antonio', 'frank'), ('Houston', 'bob')),
(('Austin', 'Lenny'), ('San Antonio', 'frank'), ('Houston', 'sunny')),
(('Austin', 'Lenny'), ('San Antonio', 'sunny'), ('Houston', 'bob')),
(('Austin', 'Lenny'), ('San Antonio', 'sunny'), ('Houston', 'frank')),
(('Austin', 'frank'), ('San Antonio', 'bob'), ('Houston', 'Lenny')),
(('Austin', 'frank'), ('San Antonio', 'bob'), ('Houston', 'sunny')),
(('Austin', 'frank'), ('San Antonio', 'Lenny'), ('Houston', 'bob')),
(('Austin', 'frank'), ('San Antonio', 'Lenny'), ('Houston', 'sunny')),
(('Austin', 'frank'), ('San Antonio', 'sunny'), ('Houston', 'bob')),
(('Austin', 'frank'), ('San Antonio', 'sunny'), ('Houston', 'Lenny')),
(('Austin', 'sunny'), ('San Antonio', 'bob'), ('Houston', 'Lenny')),
(('Austin', 'sunny'), ('San Antonio', 'bob'), ('Houston', 'frank')),
(('Austin', 'sunny'), ('San Antonio', 'Lenny'), ('Houston', 'bob')),
(('Austin', 'sunny'), ('San Antonio', 'Lenny'), ('Houston', 'frank')),
(('Austin', 'sunny'), ('San Antonio', 'frank'), ('Houston', 'bob')),
(('Austin', 'sunny'), ('San Antonio', 'frank'), ('Houston', 'Lenny'))]

因此,在第一种情况下,'bob'开车到'Austin''Lenny'开到'San Antonio''frank'开到'Houston';在第二种情况下,'bob'开车到'Austin''Lenny'开到'San Antonio''sunny'开到'Houston';等等。有效配置的总数在这里 2×3×4 = 24 ,这也是yield ed的元素数。

然而,如果你想找到最佳组合 - 你的问题中不明确的东西 - 你可以使用匈牙利算法的变体在 O(n 3 )

答案 1 :(得分:1)

使用Pandas Dataframe进行分层呈现的方法:

用df:

            bob  lenny  frank  sunny
Austin       45     15     77     33
SanAntonio   12     23     10     18
Houston      44     99     78     12

我们可以这样做:

m,n=df.shape
idx=[list(t) for t in itertools.permutations(range(n),m) ]
cash=df.values[range(m),idx]
staff=np.take(df.columns.tolist(),idx)
total=pd.DataFrame(index=staff,data=cash,columns=df.index)
total['amount']=cash.sum(axis=1)
print (total.sort_values('amount',ascending=False))

对于:

                       Austin  SanAntonio  Houston  amount
(frank, sunny, lenny)      77          18       99     194
(frank, bob, lenny)        77          12       99     188
(bob, sunny, lenny)        45          18       99     162
(bob, frank, lenny)        45          10       99     154
(bob, lenny, frank)        45          23       78     146
(frank, lenny, bob)        77          23       44     144
(sunny, bob, lenny)        33          12       99     144
(sunny, frank, lenny)      33          10       99     142
(bob, sunny, frank)        45          18       78     141
(frank, sunny, bob)        77          18       44     139
(sunny, lenny, frank)      33          23       78     134
(sunny, bob, frank)        33          12       78     123
(frank, lenny, sunny)      77          23       12     112
(lenny, sunny, frank)      15          18       78     111
(lenny, bob, frank)        15          12       78     105
(frank, bob, sunny)        77          12       12     101
(sunny, lenny, bob)        33          23       44     100
(sunny, frank, bob)        33          10       44      87
(bob, lenny, sunny)        45          23       12      80
(lenny, sunny, bob)        15          18       44      77
(lenny, frank, bob)        15          10       44      69
(bob, frank, sunny)        45          10       12      67
(lenny, bob, sunny)        15          12       12      39
(lenny, frank, sunny)      15          10       12      37