简体   繁体   English

将整数拆分为浮点数

[英]Split whole number into float numbers

Goal: split 100 into 5 random 2 decimal place numbers.目标:将100分成5随机的 2 个小数位数字。

So far, I can simulate any number of divisions.到目前为止,我可以模拟任意数量的部门。

However, these are only integers and are "balanced", in that they are the same or close in values to each other.然而,这些只是整数并且是“平衡的”,因为它们的值彼此相同或接近。 So, the output is always the same.因此,output 始终相同。

Code:代码:

def split(x, n):
 
    if(x < n):
        print(-1)
 
    elif (x % n == 0):
        for i in range(n):
            print(x//n, end =" ")
    else:
        zp = n - (x % n)
        pp = x//n
        for i in range(n):
            if(i>= zp):
                print(pp + 1, end =" ")
            else:
                print(pp, end =" ")
       
split(100, 5)
>>> 20 20 20 20 20 

Desired Output:所需的 Output:

  • List of numbers,号码列表,
  • Floating point numbers (2 dp),浮点数(2 dp),
  • Non-balanced.不平衡。

Example Desired Output:所需的示例 Output:

[10.50, 22.98, 13.23, 40.33, 12.96]

If you generate values uniformly starting with the full range for the first one, the remaining range for the second, the remaining remaining range for the third, etc., there's a 50% chance each time of getting a value larger than half the remaining range.如果您从第一个的完整范围、第二个的剩余范围、第三个的剩余范围等开始统一生成值,则每次有 50% 的机会获得大于剩余范围一半的值. This leads to a systematic bias—on average, earlier values tend to be larger than later values.这会导致系统偏差——平均而言,较早的值往往大于较晚的值。 There's a simple algorithm to avoid this and get identical distributions for all positions:有一个简单的算法可以避免这种情况并为所有位置获得相同的分布:

  1. Generate a list containing 0 and the maximum value, and then append n-1 values which are all uniformly distributed between 0 and the maximum;生成一个包含 0 和最大值的列表,然后 append n-1 个值都均匀分布在 0 和最大值之间;
  2. Sort the list;对列表进行排序; and
  3. Calculate the differences between adjacent pairs of values in the sorted list.计算排序列表中相邻值对之间的差异。

By definition the results will add up to the maximum, because they are the interval lengths between 0 and the maximum.根据定义,结果将加起来为最大值,因为它们是 0 和最大值之间的间隔长度。 Big gaps or small gaps are equally likely to fall between any of the pairs, guaranteeing identical distributions (to the extent that the PRNG is actually uniform).大间隙或小间隙同样可能落在任何对之间,保证相同的分布(在 PRNG 实际上是均匀的范围内)。

I've adopted the idea of scaling up by 100 and back to get two decimals.我采用了按比例放大 100 并返回到小数点后两位的想法。 Here it is in code:这是代码:

import random

def split(x, n, decimal=2):
    if x < n: return -1
    if decimal < 0: return -1

    x *= 10**decimal

    numbers = [0, x]
    for _ in range(n - 1):
        number = random.randint(1, x)
        numbers.append(number)
    numbers.sort()

    return [(numbers[i] - numbers[i-1]) / 10**decimal for i in range(1, n+1)]

which produces outcomes such as这会产生诸如

[10.82, 12.97, 17.92, 39.46, 18.83]
[25.99, 21.35, 29.12, 8.13, 15.41]
[5.51, 4.28, 69.59, 9.62, 11.0]
[21.39, 20.96, 11.25, 15.07, 31.33]

You can use python's builtin random library to specify random numbers, and keep subtracting that number from your total to generate more random numbers.您可以使用 python 的内置random库来指定随机数,并不断从总数中减去该数字以生成更多随机数。

Like @Kenny Ostrom suggested, you can multiply by 100 and then divide by 100 at the end to get the desired number of decimal places.就像@Kenny Ostrom 建议的那样,您可以乘以 100,然后在最后除以 100 以获得所需的小数位数。 I made it more generic by adding a kwarg decimal , in case you need a different floating point precision我通过添加一个 kwarg decimal使它更通用,以防您需要不同的浮点精度

import random

def split(x, n, decimal=2):
    if x < n: return -1
    if decimal < 0: return -1

    x *= 10**decimal

    numbers = []
    left = x
    for i in range(n):
        number = random.randint(1,left)
        numbers.append(number)
        left -= number

    return [n / 10**decimal for n in numbers]

Some example outputs一些示例输出

split(100,5) # [1.8, 67.64, 0.51, 21.88, 3.67]
split(100,5) # [29.29, 16.39, 51.54, 1.91, 0.71]
split(100,5) # [95.24, 0.79, 0.82, 2.56, 0.02]
split(100,5) # [10.18, 45.09, 30.87, 0.3, 0.68]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM