Python:根据给定的行和列的总和生成一个随机的2d整数数组



有没有办法生成一个每行和每列的固定和的2d数组?

例如

TargetArray=3行4列

每行之和=[30,20,30]

每列之和=[23,10,27,20]

我花了很多天的时间试图解决这个问题,但没有结果😢

简单的解决方案:

23 10 27 20
30  -27 10 27 20
20   20  0  0  0
30   30  0  0  0

构建代码:

R = [30, 20, 30]
C = [23, 10, 27, 20]
assert sum(R) == sum(C)
matrix = [[(0 if j else r) if i else (c if j else r+c-sum(R))
for j, c in enumerate(C)]
for i, r in enumerate(R)]

或者:

matrix = [[0 if i and j else
r if i else
c if j else
r + c - sum(R)
for j, c in enumerate(C)]
for i, r in enumerate(R)]

或者一种有点可爱的方式,总是构建一个由四种可能性组成的迷你矩阵,并选择正确的一种(假设是非空矩阵(:

x = R[0] + C[0] - sum(R)
matrix = [[[[x, c],
[r, 0]][i > 0][j > 0]
for j, c in enumerate(C)]
for i, r in enumerate(R)]

您可以使用一种名为迭代比例拟合的算法来实现这一点:https://en.wikipedia.org/wiki/Iterative_proportional_fitting.IPF允许它从行和列和向量重构非负矩阵。

有一个Python实现,称为ipfn。

from ipfn import ipfn
import numpy as np
seed = np.ones((3,4))
row_sum = [30, 20, 30]
column_sum = [23, 10, 27, 20]    
aggregates = [row_sum, column_sum]
dimensions = [[0], [1]]
IPF = ipfn.ipfn(seed, aggregates, dimensions, convergence_rate=1e-6)
X = IPF.iteration()
X = array([[ 8.625,  3.75 , 10.125,  7.5  ],
[ 5.75 ,  2.5  ,  6.75 ,  5.   ],
[ 8.625,  3.75 , 10.125,  7.5  ]])

通过改变种子,你会得到不同的结果。如果您要求X只包含整数,那么您需要使用IPF的整数版本。然而,据我所知,这方面还没有Python实现。

最新更新