Format a number containing a decimal point with leading zeroes - python

I want to format a number with a decimal point in it with leading zeros.
This
>>> '3.3'.zfill(5)
003.3
considers all the digits and even the decimal point. Is there a function in python that considers only the whole part?
I only need to format simple numbers with no more than five decimal places. Also, using %5f seems to consider trailing instead of leading zeros.

Is that what you look for?
>>> "%07.1f" % 2.11
'00002.1'
So according to your comment, I can come up with this one (although not as elegant anymore):
>>> fmt = lambda x : "%04d" % x + str(x%1)[1:]
>>> fmt(3.1)
0003.1
>>> fmt(3.158)
0003.158

I like the new style of formatting.
loop = 2
pause = 2
print 'Begin Loop {0}, {1:06.2f} Seconds Pause'.format(loop, pause)
>>>Begin Loop 2, 0002.1 Seconds Pause
In {1:06.2f}:
1 is the place holder for variable pause
0 indicates to pad with leading zeros
6 total number of characters including the decimal point
2 the precision
f converts integers to floats

print('{0:07.3f}'.format(12.34))
This will have total 7 characters including 3 decimal points, ie. "012.340"

Like this?
>>> '%#05.1f' % 3.3
'003.3'

Starting with a string as your example does, you could write a small function such as this to do what you want:
def zpad(val, n):
bits = val.split('.')
return "%s.%s" % (bits[0].zfill(n), bits[1])
>>> zpad('3.3', 5)
'00003.3'

With Python 3.6+ you can use the fstring method:
f'{3.3:.0f}'[-5:]
>>> '3'
f'{30000.3:.0f}'[-5:]
>>> '30000'
This method will eliminate the fractional component (consider only the whole part) and return up to 5 digits. Two caveats: First, if the whole part is larger than 5 digits, the most significant digits beyond 5 will be removed.
Second, if the fractional component is greater than 0.5, the function will round up.
f'{300000.51:.0f}'[-5:]
>>>'00001'

Related

Alternative to Python's str() which does not change 0.4810 to 0.481? [duplicate]

How do I format a floating number to a fixed width with the following requirements:
Leading zero if n < 1
Add trailing decimal zero(s) to fill up fixed width
Truncate decimal digits past fixed width
Align all decimal points
For example:
% formatter something like '{:06}'
numbers = [23.23, 0.123334987, 1, 4.223, 9887.2]
for number in numbers:
print formatter.format(number)
The output would be like
23.2300
0.1233
1.0000
4.2230
9887.2000
numbers = [23.23, 0.1233, 1.0, 4.223, 9887.2]
for x in numbers:
print("{:10.4f}".format(x))
prints
23.2300
0.1233
1.0000
4.2230
9887.2000
The format specifier inside the curly braces follows the Python format string syntax. Specifically, in this case, it consists of the following parts:
The empty string before the colon means "take the next provided argument to format()" – in this case the x as the only argument.
The 10.4f part after the colon is the format specification.
The f denotes fixed-point notation.
The 10 is the total width of the field being printed, lefted-padded by spaces.
The 4 is the number of digits after the decimal point.
It has been a few years since this was answered, but as of Python 3.6 (PEP498) you could use the new f-strings:
numbers = [23.23, 0.123334987, 1, 4.223, 9887.2]
for number in numbers:
print(f'{number:9.4f}')
Prints:
23.2300
0.1233
1.0000
4.2230
9887.2000
In python3 the following works:
>>> v=10.4
>>> print('% 6.2f' % v)
10.40
>>> print('% 12.1f' % v)
10.4
>>> print('%012.1f' % v)
0000000010.4
You can also left pad with zeros. For example if you want number to have 9 characters length, left padded with zeros use:
print('{:09.3f}'.format(number))
Thus, if number = 4.656, the output is: 00004.656
For your example the output will look like this:
numbers = [23.2300, 0.1233, 1.0000, 4.2230, 9887.2000]
for x in numbers:
print('{:010.4f}'.format(x))
prints:
00023.2300
00000.1233
00001.0000
00004.2230
09887.2000
One example where this may be useful is when you want to properly list filenames in alphabetical order. I noticed in some linux systems, the number is: 1,10,11,..2,20,21,...
Thus if you want to enforce the necessary numeric order in filenames, you need to left pad with the appropriate number of zeros.
See Python 3.x format string syntax:
IDLE 3.5.1
numbers = ['23.23', '.1233', '1', '4.223', '9887.2']
for x in numbers:
print('{0: >#016.4f}'. format(float(x)))
23.2300
0.1233
1.0000
4.2230
9887.2000
This will print 76.66:
print("Number: ", f"{76.663254: .2f}")
Using f-string literals:
>>> number = 12.34
>>> print(f"{number}")
12.34
>>> print(f"{number:10f}")
12.340000
>>> print(f"{number:10.4f}")
12.3400
The 10.4f after the colon : is the format specification, with 10 being the width in characters of the whole number (including spaces), and the second number 4 being the number of decimal places, and the f standing for floating-point number.
It's also possible to use variables instead of hard-coding the width and the number of decimal places:
>>> number = 12.34
>>> width = 10
>>> decimals = 4
>>> print(f"{number:{width}.{decimals}f}")
12.3400
In Python 3.
GPA = 2.5
print(" %6.1f " % GPA)
6.1f means after the dots 1 digits show if you print 2 digits after the dots you should only %6.2f such that %6.3f 3 digits print after the point.
I needed something similar for arrays. That helped me
some_array_rounded=np.around(some_array, 5)
I tried all the options like
pd.options.display.float_format = '{:.4f}'.format
pd.set_option('display.float_format', str)
pd.set_option('display.float_format', lambda x: f'%.{len(str(x%1))-2}f' % x)
pd.set_option('display.float_format', lambda x: '%.3f' % x)
but nothing worked for me.
so while assigning the variable/value (var1) to a variable (say num1) I used round(val,5) like
num1 = round(var1,5)
This is a crude method as you have to use this round function in each assignment. But this ensures you control on how it happens and get what you want.

Round 2 digit after decimal point after zero in Python

Assume I have a float:
x = 0.0005953829144211724
I have to round it after the decimal to:
x = 0.00059
Similarly, if
x = 0.00000046605219739046376
then the result should be
x = 0.00000046
Is there any inbuild function in python to do this?
You can use a nested format with Decimal. The first format does the rounding using the "g" specifier. The second one prints all the digits, without scientific notation, using the decimal value of the rounded string:
from decimal import Decimal
x = 0.0005953829144211724
print(f"{Decimal(f'{x:.2g}'):f}") # 0.0006
print(f"{Decimal(f'{x:.3g}'):f}") # 0.000595
print(f"{Decimal(f'{x:.4g}'):f}") # 0.0005954
x = 0.00000046605219739046376
print(f"{Decimal(f'{x:.2g}'):f}") # 0.00000047
print(f"{Decimal(f'{x:.3g}'):f}") # 0.000000466
print(f"{Decimal(f'{x:.4g}'):f}") # 0.0000004661
Note that this DOES round the value to the specified precision, contrary to your examples which truncate the mantissa instead of rounding it
As shown in the other answer, if you want a certain number of significant digits, you should format the number in scientific notation. If, however, you want those significant digits in the "normal" format, you might either convert that scientific notation back to float (thus "forgetting" all the "insignificant" digits) and then back to string and rstrip all excess zeros, or maybe use a regular expression:
>>> x = 0.00000046605219739046376
>>> f'{float(f"{x:.2g}"):.20f}'.rstrip("0")
'0.00000047'
>>> re.match(r"0\.0*[^0]{2}", f"{x:.20f}").group()
'0.00000046'
Note: i) The .20f here means "print in normal decimal format with 20 places after the decimal", where the 20 is kind of arbitrary. ii) The regex will not round but just trim the number.
You can do something close with the g specifier in an f-string:
x = 0.00000046605219739046376
print(f'{x:.2g}')
This will print the result in "scientific notation"
4.7e-07
Similarly:
x = 0.0005953829144211724
print(f'{x:.2g}')
results in
0.0006
since it rounds up.

Format float with fixed amount of digits python

I would like to format my floats with a fixed amount of digits. Right now I'm doing the following
format="%6.6g"
print(format%0.00215165)
print(format%1.23260)
print(format%145.5655)
But this outputs
0.00215165
1.2326
145.565
I also tried format="%6.6f" but it doesn't really give what I want either...
0.002152
1.232600
145.565500
What would be a good way to format the numbers so that all of them have exactly width 6 (and no spaces) like so ?
0.002152
1.232600
145.5655
This is complicated because you want the precision (number of decimals) to depend on the available space, while the general thrust of floating-point formatting is to make the number of significant digits depend on the available space. To do what you want you need a function that computes the desired number of decimals from the log of the number. There isn't, so far as I know, a built-in function that will do this for you.
def decimals(v):
return max(0, min(6,6-int(math.log10(abs(v))))) if v else 6
This simply takes the log of number and truncates it to int. So 10-99 -> 1, 100-999 -> 2 etc. You then use that
result to work out the precision to which the number needs to be formatted. In practice the
function is more complex because of the corner cases: what to do with negative numbers, numbers that underflow, etc.
For simplicity I've deliberately left your figure of 6 decimals hard-coded 3 times in the function.
Then formatting isn't so hard:
>>> v = 0.00215165
>>> "{0:.{1}f}".format(v, decimals(v))
'0.002152'
>>> v2 = 1.23260
>>> "{0:.{1}f}".format(v2, decimals(v2))
'1.232600'
>>> v3 = 145.5655
>>> "{0:.{1}f}".format(v3, decimals(v3))
'145.5655'
>>> vz = 0e0 # behaviour with zero
>>> "{0:.{1}f}".format(vz, decimals(vz))
'0.000000'
>>> vu = 1e-10 # behaviour with underflow
>>> "{0:.{1}f}".format(vu, decimals(vu))
'0.000000'
>>> vo = 1234567 # behaviour when nearly out of space
>>> "{0:.{1}f}".format(vo, decimals(vo))
'1234567'
>>> voo = 12345678 # behaviour when all out of space
>>> "{0:.{1}f}".format(voo, decimals(voo))
'12345678'
You can use %-notation for this instead of a call to format but it is not very obvious or intuitive:
>>> "%.*f" % (decimals(v), v)
'0.002152'
You don't say what you want done with negative numbers. What this approach does is to take an extra
character to display the minus sign. If you don't want that then you need to reduce the number of
decimals for negative numbers.

How to fix floating point decimal to two places even if number is 2.00000

This is what I have:
x = 2.00001
This is what I need:
x = 2.00
I am using:
float("%.2f" % x)
But all I get is:
2
How can I limit the decimal places to two AND make sure there are always two decimal places even if they are zero?
Note: I do not want the final output to be a string.
This works:
'%.2f" % float(x)
Previously I answered with this:
How about this?
def fmt2decimals(x):
s = str(int(x*100))
return s[0:-2] + '.' + s[-2:]
AFAIK you can't get trailing zeros with a format specification like %.2f.
If you can use decimal (https://docs.python.org/2/library/decimal.html) instead of float:
from decimal import Decimal
Decimal('7').quantize(Decimal('.01'))
quantize() specifies where to round to.
https://docs.python.org/2/library/decimal.html#decimal.Decimal.quantize
Have you taken a look at the decimal module? It allows you to do arithmetic while maintaining the proper precision:
>>> from decimal import Decimal
>>> a = Decimal("2.00")
>>> a * 5
Decimal('10.00')
>>> b = Decimal("0.05")
>>> a * b
Decimal('0.1000')
Python also has a builtin "round" function: x = round(2.00001, 2) I believe is the command you would use.
Well, in Python, you can't really round to two zeroes without the result being a string. Python will usually always round to the first zero because of how floating point integers are stored. You can round to two digits if the second digit is not zero, though.
For example, this:
round(2.00001, 2)
#Output: 2.0
vs this:
round(2.00601, 2)
#Output: 2.01

Convert number to string scientific notation fixed length

I have a normal float number such as "1234.567" or "100000". I would like to convert it to a string such that the precision is fixed and the number is in scientific notation. For example, with 5 digits, the results would be "1.2346e003 and "1.0000e005", respectively. The builtin Decimal number -> string functions will round it if it can, so the second number would be only "1e005" even when I want more digits. This is undesirable since I need all numbers to be the same length.
Is there a "pythonic" way to do this without resorting to complicated string operations?
precision = 2
number_to_convert = 10000
print "%0.*e"%(precision,number_to_convert)
is that what you are asking for?
You can use the %e string formatter:
>>> '%1.5e'%1234.567
'1.23457e+03'
>>> "%1.5e"%100000
'1.00000e+05'
%x.ye where x = min characters and y = max precision.
If you need to keep the 3-digit exponent like in your example, you can define your own function. Here's an example adapted from this answer:
def eformat(f, prec, exp_digits):
s = "%.*e"%(prec, f)
mantissa, exp = s.split('e')
return "%se%0*d"%(mantissa, exp_digits, int(exp))
>>> print eformat(1234.567, 4, 3)
1.2346e003

Categories

Resources