将列表值分配给另一个列表

时间:2020-03-08 14:20:58

标签: python list

我有两个长度相同的列表,一个包含整数和一个浮点数。我想将每个浮点数分配给一个整数-相对

我是说:相对

  • 较高个整数应该有一个较高机会来接收一个较低浮点数
  • 个整数应该有一个较低的机会来获得一个浮点数

要进行分配,只需将浮点数附加到结果数组即可,这样integers[index]与分配的result[index]匹配。

由于我在谈论机会,因此我不能简单地对一个列表进行降序排序,而对一个列表进行升序排序并匹配它们。

我不太确定如何解决我的问题。我正在寻找一些我从未听说过的功能/模块-或一如既往地首选:纯python内置解决方案:)

#INDICES:   0    1    2    3    4    5    6    7    8    9  

integers = [5,   5,   2,   4,   3,   1,   4,   5,   2,   3  ]
floats =   [0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5]


#possible result (could be different):
result =   [0.2, 0.3, 0.3, 0.5, 0.7, 0.8, 0.6, 0.1, 0.3, 0.5]

#the result values are assigned to the integers at the same index

如您所见,在结果示例中,result[9]==0.5被分配给integers[9]==3,而result[6]==0.6被分配给integers[6]==4。这是列表其余部分的一个例外,因为通常将较高的浮点数分配给较低的整数。

2 个答案:

答案 0 :(得分:1)

类似这样的事情应该可以解决:

import random

def shuffle(ints, floats):

    new_ints = list(sorted(ints))
    new_floats = list(sorted(floats))

    def weight(x, n):
        # implement your own weight system here
        # maybe `n+x` - just make sure that as
        # x increases the weight increases
        return x

    def gen_weights(n):
        return [weight(x,n) for x in range(1,n+1)]

    result = []
    while new_ints:
        i = random.choices(range(len(new_ints)), gen_weights(len(new_ints)))[0]
        result.append((new_ints.pop(0), new_floats.pop(i)))

    new_result = []
    for x in ints:
        for i, (j, f) in enumerate(result):
            if j == x:
                new_result.append(f)
                del result[i]
                break
    return new_result

random.seed(1)

in1 = [5,   5,   2,   4,   3,   1,   4,   5,   2,   3  ]
in2 = [0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5]

result = shuffle(in1, in2)
print(result)

输出:

[0.3, 0.1, 0.8, 0.5, 0.3, 0.3, 0.7, 0.2, 0.6, 0.5]

从本质上讲,它会同时对两个列表进行排序,然后为每个浮点数创建一组权重,以确定要选择它们的可能性。它从浮点数集中删除该索引,并选择一个整数集的第一个值,并将其存储在结果列表中,从整数集和浮点数集中删除项目。

最后,该函数遍历原始int列表中的每个项目,并在结果列表中找到对应的整数值。它将删除该值,并将其附加到输出(new_result)列表中。


如果您不喜欢线性权重系统,请将return x函数中的weight值替换为其他任何递增函数。确保x的较高值具有较高的返回值。


希望这会有所帮助:)

答案 1 :(得分:1)

这是一个相对简单的方法:

import random

STD_DEV = 2

integers = sorted([5, 5, 2, 4, 3, 1, 4, 5, 2, 3], reverse=True)
floats = sorted([0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5])

results = []
for i in range(0, len(integers)): 
    noisy_index = min(max(int(random.gauss(i, STD_DEV)), 0), len(floats)-1)
    results.append(floats[noisy_index])

print(results)
# [0.1, 0.2, 0.3, 0.2, 0.5, 0.3, 0.5, 0.5, 0.8, 0.7]

它首先对降序的整数进行排序,然后对浮点数进行升序,然后遍历整数索引并通过从围绕该索引值的高斯分布中采样来确定要选择的浮点值的索引。 STD_DEV值将使您可以控制选择更多索引的频率...我选择STD_DEV = 2是因为它似乎表现合理(即index = 0不太可能跳到index = 9)。

请注意,这实际上是一种相对加权方法。排序后的整数索引值确定了最有可能选择的 浮点数,但是如果前两个数字为5, 5...500, 5...,则浮点数的行为相同。

编辑:如果希望整数值具有超出其相对顺序的权重,则一种方法是根据该值缩放高斯分布的标准偏差。这是一种方法(可以通过多种方式来实现),它只是根据整数值与均值之间的距离来缩放标准偏差:

import random

BASE_STD_DEV = 2

integers = sorted([5, 5, 2, 4, 3, 1, 4, 5, 2, 3], reverse=True)
floats = sorted([0.1, 0.2, 0.3, 0.3, 0.3, 0.7, 0.6, 0.8, 0.5, 0.5])

avg_int = sum(integers)/len(integers)
max_dist = max([abs(i - avg_int) for i in integers])

results = []
for i, integer in enumerate(integers):
    factor = 1 - abs(integer - avg_int) / max_dist
    std_dev = BASE_STD_DEV * factor
    noisy_index = min(max(int(random.gauss(i, std_dev)), 0), len(floats)-1)
    results.append(floats[noisy_index])

print(results)
# [0.1, 0.2, 0.3, 0.2, 0.5, 0.3, 0.5, 0.5, 0.8, 0.7]

您可以轻松地对此进行调整,以使其具有最小标准偏差或最小/最大factor,因为当前极限值没有标准偏差。