Python 函数 根据给定的时间间隔将整数转换为 bins

Python function Converting an integer to bins as per given interval

提问人:Arun Kumar Khattri 提问时间:7/18/2023 更新时间:7/18/2023 访问量:59

问:

我正在尝试根据给定的时间间隔将整数 () 转换为 bins。 箱大小(间隔)为num[1, 200), [200, 400), [400, 800), [800, 1200), [1200, num]

我正在以一种粗暴的方式做到这一点......

def create_bins(num):
    """Create Bins as per given intervals."""
    s1, s2, s3, s4 = 199, 200, 400, 400
    if num > 1200:
        res = [s1, s2, s3, s4, num - (s1 + s2 + s3 + s4)]
    elif num < 1200 and num >= 800:
        res = [s1, s2, s3, num - (s1 + s2 + s3)]
    elif num < 800 and num >= 400:
        res = [s1, s2, num - (s1 + s2)]
    elif num < 400 and num >= 200:
        res = [s1, num - s1]
    else:
        res = [num]

    return res

这个函数用于返回正确的结果。但是,我相信有更好的方法可以完成它......create_bins(1041)[199, 200, 400, 242]

如果您能带领我找到解决此类问题的更好解决方案,将不胜感激。

Python 分箱

评论

1赞 Julien 7/18/2023
您应该将其发布在代码审查中。
0赞 Arun Kumar Khattri 7/18/2023
@Julien 我敢肯定这不是解决问题的理想方法。因此,与其进行代码审查,不如寻找更好的解决方案。代码中有很多重复,但是,不知何故,该代码对我来说变得难以捉摸......
0赞 Julien 7/18/2023
这就是代码审查的意义所在。此外,“更好”是主观的,您的代码没有问题。如何询问
0赞 Julien 7/18/2023
您可以将总和替换为它们的值,因为它们是常量。s1 + ...
0赞 7/18/2023
在什么意义上更好?

答:

0赞 Jenil saliya 7/18/2023 #1

这可能是个好主意。

  def create_bins_new(num):
        val = [199,200,400,400]
        out = []
        for v in val:
            if v < num:
                out.append(v)
                num -= v
        out.append(num)
        return out

评论

0赞 Julien 7/18/2023
或不...这比 OP 的解决方案慢得多。
0赞 7/18/2023
@Julien:基本上?你能证实吗?
0赞 Julien 7/18/2023
使用 %timeit 发现它慢了 50%。
0赞 7/18/2023
@Julien:预期时间取决于 的值分布。num
0赞 Julien 7/18/2023
在最好的情况下是一样的,在最坏的情况下是一样的;更慢。
0赞 user21508463 7/18/2023 #2

如果条柱数量非常多,则计算条柱大小的前缀总和,通过二进制搜索在此列表中找到并组合结果。num

import bisect

# Data arrays
bins= [199, 200, 400, 400]
prefix= [sum(bins[:i]) for i in range(len(bins)+1)]

# Try various values
for num in [1, 150, 199, 200, 201, 798, 799, 800, 801, 1041, 2000]:
    # Search and concatenete
    index= bisect.bisect_left(prefix, num) - 1
    print(num, bins[:index] + [num - prefix[index]])

输出:

1 [1]
150 [150]
199 [199]
200 [199, 1]
201 [199, 2]
798 [199, 200, 399]
799 [199, 200, 400]
800 [199, 200, 400, 1]
801 [199, 200, 400, 2]
1041 [199, 200, 400, 242]
2000 [199, 200, 400, 400, 801]

评论

1赞 Julien 7/18/2023
3 个选项中最慢的......
0赞 7/18/2023
@Julien:“如果垃圾箱数量非常多”,你看不懂吗?当然,前缀必须一劳永逸地计算。