在第一个元素在特定范围内的元组中查找元组列表中的最小值

Posted

技术标签:

【中文标题】在第一个元素在特定范围内的元组中查找元组列表中的最小值【英文标题】:Find minimum in a list of tuple among those tuples whose first elements are within a specific range 【发布时间】:2018-12-26 18:06:30 【问题描述】:

我有一个元组列表如下:

list = [(9.9394, 0.9924), (9.8428, 0.6171), (9.9023, 0.5584), (9.8369, 1.0), (9.2106, 0.5339), (9.9748, 0.7131), (9.3257, 0.02725), (11.2865, 0.849), (10.4556, 0.7542), (10.1655, 0.9792), (10.3677, 0.5712), (10.5253, 0.8986), (10.5186, 0.5215)]

我想制作另一个由 7 个元素组成的列表,其中每个元素都是 list 的第二个元素中的最小值,这些元素的第一个元素在特定范围内。

第一个元素对应 bin (8.0,8.6),第二个元素对应 bin (8.6,9.2),第三个元素对应 bin (9.2,9.8),第四个元素对应 bin (9.8,10.4),第五个到bin(10.4,11.0),第六个到bin(11.0,11.6),最后第七个到bin(11.6,12.2),都对应list中元组的第一个元素。

示例:第四个元素对应于第四个 bin (9.8,10.4)。 list 中有 7 个元组,它们的第一个元素在此范围内:

(9.9394, 0.9924), (9.8428, 0.6171), (9.9023, 0.5584), (9.8369, 1.0), (9.2106, 0.5339), (9.9748, 0.7131), (9.3257, 0.02725)

所以,我的新列表的第 4 个元素应该是第二个元素中的最小值:

0.9924、0.6171、0.5584、1.0、0.5339、0.7131、0.02725

0.02725

是否有以下代码的任何较短版本来建立所有七个元素,从而以这种方式建立新的最小值列表?最短的答案将被接受。

dm7=0.6
item1, item2, item3, item4, item5, item6, item7 = 0, 0, 0, 0, 0, 0, 0
set1, set2, set3, set4, set5, set6, set7 = [], [], [], [], [], [], []
list = [(9.9394, 0.9924), (9.8428, 0.6171), (9.9023, 0.5584), (9.8369, 1.0), (9.2106, 0.5339), (9.9748, 0.7131), (9.3257, 0.02725), (11.2865, 0.849), (10.4556, 0.7542), (10.1655, 0.9792), (10.3677, 0.5712), (10.5253, 0.8986), (10.5186, 0.5215)]

for item in list:
    if (8. +  0*dm7 <= item[0] <= 8. +  1*dm7):
        set1.append(item[1]) 
        item1 = min(set1)
    elif (8. +  1*dm7 <= item[0] <= 8. +  2*dm7):
        set2.append(item[1])
        item2 = min(set2)
    elif (8. +  2*dm7 <= item[0] <= 8. +  3*dm7):
        set3.append(item[1])
        item3 = min(set3)
    elif (8. +  3*dm7 <= item[0] <= 8. +  4*dm7):
        set4.append(item[1])
        item4 = min(set4)
    elif (8. +  4*dm7 <= item[0] <= 8. +  5*dm7):
        set5.append(item[1])
        item5 = min(set5)
    elif (8. +  5*dm7 <= item[0] <= 8. +  6*dm7):
        set6.append(item[1])
        item6 = min(set6)
    elif (8. +  6*dm7 <= item[0] <= 8. +  7*dm7):
        set7.append(item[1])
        item7 = min(set7)

new_list = [item1, item2, item3, item4, item5, item6, item7]

【问题讨论】:

您想用哪种语言编写代码?请为此添加相应的标签。 另外,你试过什么?我有一个解决方案给你,但如果你没有尝试过,我不愿意解决“家庭作业”问题。 好的,谢谢,我现在添加它。顺便说一句,这不是家庭作业。我只是在自学python。 哦,等等!我只是对索引有疑问。现在,我正在产生结果。但是,很高兴获得更短的代码版本。 好的,因为你正在学习。看看bisect 模块。我认为它将有效地解决您的情况。可扩展的解决方案。基本上将您的 bin 阈值设置为示例中的“断点”。您可以创建索引与 bin 编号匹配的集合列表。 【参考方案1】:

这就是我想出的,假设我了解你的情况。

from bisect import bisect

items = [(9.9394, 0.9924), (9.8428, 0.6171), (9.9023, 0.5584), (9.8369, 1.0), (9.2106, 0.5339), (9.9748, 0.7131), (9.3257, 0.02725), (11.2865, 0.849), (10.4556, 0.7542), (10.1655, 0.9792), (10.3677, 0.5712), (10.5253, 0.8986), (10.5186, 0.5215)]

thresholds = [x / 10 for x in range(80, 123, 6)] # [8.0, 8.6, 9.2, 9.8, 10.4, 11.0, 11.6, 12.2]
bins = [list() for _ in range(len(thresholds) - 1)] # Set number of bins to 1 less than threshold points

for sorting_key, value in items: # Iterate over items to place into respective bin
    bins[bisect(thresholds, sorting_key) - 1].append(value)

from pprint import pprint
pprint(bins)

输出将是:

[[],
 [],
 [0.5339, 0.02725],
 [0.9924, 0.6171, 0.5584, 1.0, 0.7131, 0.9792, 0.5712],
 [0.7542, 0.8986, 0.5215],
 [0.849],
 []]

如果您需要获取最小值,只需在每个函数上使用内置的min() 函数即可。

min_each = [min(b) if b else None for b in bins] # [None, None, 0.02725, 0.5584, 0.5215, 0.849, None]

在上面的代码中,我没有使用map(min, bins),因为min()不能对空列表进行操作。

【讨论】:

然后我们必须在每个子集中选择最小值。你也可以添加吗? 这很有趣, @Allan,更新了我的答案以反映这一点。【参考方案2】:

您可以使用numpy 来提高性能。使用numpy.digitize,您可以计算每个项目所属的组。然后通过一些重塑,您可以计算每个组的最小值。

import numpy as np


items = [(9.9394, 0.9924), (9.8428, 0.6171), (9.9023, 0.5584), (9.8369, 1.0), (9.2106, 0.5339), (9.9748, 0.7131), (9.3257, 0.02725), (11.2865, 0.849), (10.4556, 0.7542), (10.1655, 0.9792), (10.3677, 0.5712), (10.5253, 0.8986), (10.5186, 0.5215)]
items = np.asarray(items)

bins = np.linspace(8.0, 12.2, 8)
indices = np.digitize(items[:, 0], bins)  # Check which item corresponds to which bin.
mask = np.tile(indices, (bins.size, 1)) == np.arange(bins.size)[:, None]  # For each group check the members.

result = np.where(mask, items[:, 1], np.inf).min(axis=1)
result[result == np.inf] = 0  # Set default value if no items are available for that group.

print('result: ', result)

【讨论】:

谢谢 a_guest,很好!我喜欢,

以上是关于在第一个元素在特定范围内的元组中查找元组列表中的最小值的主要内容,如果未能解决你的问题,请参考以下文章

对本身位于元组中的元组(可迭代的可迭代)求和的最有效方法是啥?

Swift flatMap:如何从数组中仅删除元组中特定元素为零的元组?

python 元组操作总结

从Haskell中的元组中提取第n个元素(其中n和元组被赋予参数)

在 Python 元组列表中查找重复项

python学习之第五篇:Python中的元组及其所具有的方法