Python中计数器的线性组合



我有一些Counter对象,如下所示,表示等式的左手边和右手边:

左侧:(Counter({22.99: 1}), Counter({12.011: 2, 15.999: 2}), Counter({12.011: 7}))

右侧:Counter({12.011: 15, 15.999: 1})

我的目标是找到方程两边的共同元素,然后确定左边的线性组合,可以得到右边。

在上面的例子中,要求解的方程是:

2A*12.011 + 7B*12.011 = 15W*12.011
2A*15.999 = W*15.999

我预计这项操作将涉及将计数器字典转换为矩阵,以求解线性方程组,但我不知道如何做到这一点。

这里有一个非常符合您的方法的解决方案。

  1. 将每个计数器转换为一个向量,将不同的ID视为单独的维度
  2. 求解线性方程组

from collections import Counter
import numpy as np
from scipy import linalg

lhs = (Counter({22.99: 1}), Counter({12.011: 2, 15.999: 2}), Counter({12.011: 7}))
rhs = Counter({12.011: 15, 15.999: 1})
# get unique keys that occur in any Counter in 2D
# each unique key represents a separate dimension
ks = np.array([*set().union(rhs, *lhs)])[:, None]
# get a helper function to convert Counters to vectors
ctr_to_vec = np.vectorize(Counter.__getitem__)
lhs_mat = ctr_to_vec(lhs, ks)
rhs_vec = ctr_to_vec(rhs, ks)
# compute coefficients solving the least-squares problem
coefs = linalg.lstsq(lhs_mat, rhs_vec)[0]
is_linear_comb = np.allclose(lhs_mat @ coefs, rhs_vec)

最新更新