蛮力特征选择 - 跨列表组合对项目求和

Brute force feature selection - sum items across list combinations

我有 x 个参数列表和一个包含 x 个列表的列表。通过将每个列表中的每个相应项目相加来计算总分。

例如,我有 2 个列表和一个主列表,如下所示:

a = [1,2]
b = [2,1]
mainList = ['a','b']

我想要所有独特的组合 - 这是由:

for L in range(0, len(mainList)+1):
for subset in itertools.combinations(mainList, L):
    print(subset)

输出:

()
('a',)
('b',)
('a', 'b')

对于每个排列,我希望通过对每个包含列表的项目求和来创建一个包含总分的新列表。

因此,例如,在这种情况下,所需的输出将是:

[0,0] 
[1,2] #i.e. just a
[2,1] #i.e. just b
[3,3] #i.e. a+b

这就是我遇到的问题 - 我不确定如何获得上述所需的输出。

我怀疑我把它复杂化了 & 有一个快速的方法可以做到这一点。

您需要以某种方式将 a 和 b 字符串与相应的列表连接起来。我认为最干净的方法是有一个包含列表名称和列表及其值的字典。

这是一个例子:

list_dict = {'a': a, 'b': b}

for L in range(0, len(mainList)+1):
    for subset in itertools.combinations(mainList, L):
        temp = [0, 0]
        for sub in subset:
            temp[0] += list_dict[sub][0]
            temp[1] += list_dict[sub][1]
        print(temp)

使用 zip(*...) 到 'transpose' 列表(例如将 [[1, 2], [3, 4]] 转换为 [(1, 3), (2, 4)])然后对元素求和:

a = [1, 2]
b = [3, 4]
main = [a, b]  # make main a list of the lists rather than text labels

for length in range(len(main)+1):
    for subset in itertools.combinations(main, length):
        result = [sum(t) for t in zip(*subset)]
        if result:
            print(result)
        else:
            print([0] * len(main[0]))

但是请注意,第一个总和(没有列表的总和)是 [] 因此我们需要一个特定的行来替换它。

如果您需要保留标签 'a', 'b' 然后制作 main 字典:

a = [1, 2]
b = [3, 4]
main = {'a': a, 'b': b}
list_length = len(list(main.values())[0])
for length in range(len(main)+1):
    for subset in itertools.combinations(main, length):
        if subset:
            print(subset, [sum(t) for t in zip(*[main[key] for key in subset])])
        else:
            print(subset, [0] * list_length)

或者,也许更简单,使用 pandas:

import pandas as pd
main = pd.DataFrame({"a": [1, 2], "b": [3, 4]})
for length in range(len(main)+1):
    for subset in itertools.combinations(main, length):
        print(subset, main[list(subset)].sum(axis=1).to_list())